2017-10-17 62 views
-1

我正在处理一个处理monetairy金额的PHP脚本,因此需要精确到2位小数。为此,我将用户输入转换为一个数字,并将其乘以100,然后将其转换为int。这工作正常,直到我最近发现一个数字,当投到int时增加1。PHP(int)生成错误的数字

的故障代码:

$number = (int)(str_replace(',','.',$_POST["input"])*100); 

,让问题的数量2509,22(我住在荷兰,所以我们使用逗号为小数,因此在上面的代码行的str_replace函数)。 该值创建整数$ number 250921,显然是1太低。 我知道,INT是有限制的,但这个数字是很好的限制之内就我所知...

+0

为什么你需要将它设置为int?这样做的目的是什么?这个int旁边会发生什么? – Andreas

+0

我使用它来确保输入不包含2位以上的小数。如前所述,这是财务信息,这是为了防止用户在金融系统中输入小于可能的分数。 – Discoverer

+1

改为使用bcmath。除非您完全确定输出结果并通过代码判断,否则绝对不要使用浮点操作,我相信您不会。您可以在这里阅读更多关于浮点数精度的信息http://php.net/manual/en/language.types.float.php –

回答

-1

当你乘以100号,你实际上并没有得到250922但sometging littlebit较低(250921,999 ....)

(int)每次向下取整,因此您需要在“int-ing”之前轮换:

$number = intval(round(str_replace(',','.',"2509,22")*100)); 
+0

这是个窍门。在其他回复中,我已经知道2809.22 * 100导致他浮点数250921.99999999997,并且当直接转换为int时,小数点被丢弃。你添加的“圆”解决了这个问题。 – Discoverer

+0

不,圆不解决'2509,225'变成'250923'。 – AbraCadaver

2

当您100乘以字符串你得到一个float其表示并不总是你的期望在这种情况下,250921.99999999997。与看它:

echo serialize(str_replace(',','.','2509,22')*100); 

然后你施放一个integer其trucates分数获得250921。见Is floating point math broken?

的解决办法是删除逗号并使用如和可选强制转换为integer

$number = (int)str_replace(',', '', '2509,22'); 

对于进入太多小数用户的问题,您应该使用两个输入,一个用于整数和一个分数和/或限制/验证输入格式正确。但是,您可以先格式化数字:

echo $number = (number_format(str_replace(',', '.', '2509,22'), 2, '.', '')*100); 
+0

好的,谢谢!和整数只是把它放下我猜。你知道我应该用什么类型的演员来获得正确的电话号码吗? – Discoverer

+1

因为当用户多次点击一个按钮(所以他把2509222放在输入框中)时,将被存储的数字将会太高。 – Discoverer

+0

@发现者1)如果在小数点后有两位数以上的数字(或逗号:),则拒绝输入。2)在继续和/或允许撤消方法之前,向客户端提供验证值。用户可能无意中使用了“错误的”分隔符*和*键入一个额外的数字。 – user2864740

0

您可以使用正则表达式来匹配int和零 - 两位小数。
这不会做任何转换,也不会增加或转换任何东西。
它将被视为一个字符串,没有任何变化,但小数的数量。

$input = "2509,2222222"; 
// Regex number comma number (zero - two) 
Preg_match("/(\d+),*(\d{0,2})/", $input, $m); 
Unset($m[0]); // remove full match 

Echo implode("", $m); // implode parts 

https://3v4l.org/MjcYV

+0

问题是数字也应该被允许以点而不是逗号输入。当然,你也可以删除它,但是当用户输入错误的数量时(比如2509,222点击按钮的次数太多),那么金额会是2509222,这太高了。 – Discoverer

+0

这确实可行。就我个人而言,我认为我将使用David Bubenik建议的解决方案,因为这也允许输入数字而不会有任何小数。用户在他们的方式并不是很精确,所以我试图尽可能灵活,但谢谢你的建议! – Discoverer

+0

@发现者的家伙。当您发布问题时,请发布我们需要的所有信息以帮助您。你不断添加信息,这真的很烦人。 – Andreas