我在java中编写了这段代码:
String[] tokens = strLine.split(delims);
SimpleOrderRequest bet = new SimpleOrderRequest();
long Id = Long.parseLong(tokens[1].trim());
byte polarity = Byte.parseByte(tokens[2].trim());
float price = Float.parseFloat(tokens[3].trim());
float stake = Float.parseFloat(tokens[4].trim());
bet.selectionId = Id;
bet.polarity = polarity;
bet.stake = new BigDecimal(stake) ;
bet.price = new BigDecimal(price) ;
令牌[1],令牌[2],令牌[3],令牌[4]是不同格式的数字。问题是我必须将数字切换到逗号后的第一个数字,以便将数据发送到wsdl服务。也就是说,当我读到的字符串是:
0.00426, 12955094, 1, 100., 1.
0.00050, 12954726, 1, 100., 1.
一切正常,bet.stake = 1。并且bet.price = 100。但是当字符串的格式为:
0.00154, 13189533, 1, 2.10, 34.77
然后bet.stake = 34.770000457763671875和bet.price = 2.099999904632568359375,并且wsdl服务不允许我发出请求,所以我必须减少号码。我在解析数字时可以直接执行此操作吗?如果没有我必须做的事情?
答案 0 :(得分:7)
您不应该首先使用float
来表示货币值。只需使用:
BigDecimal price = new BigDecimal(tokens[3].trim());
(等)
看起来您在SimpleOrderRequest
中拥有正确的数据类型 - 那么为什么要引入二进制浮点转换?
了解二进制浮点的工作原理非常重要 - Stack Overflow上有很多关于它的问题。基本上,您通常应该使用float
和double
来表示“自然”值,例如身高和体重,其中幅度非常重要,但实际上并不存在精确值 - 并使用BigDecimal
对于“人工”值,您可以确定完全 $ 1.10。
答案 1 :(得分:0)
通常情况下,我建议在使用String.format
打印数字时进行舍入,并在此之前以更好的精度处理数据。但由于您的存根接受BigDecimals
,您必须使用setScale()
:
bet.price = new BigDecimal(tokens[3].trim()).setScale(1, RoundingMode.HALF_EVEN);
(你也应该注意Jon Skeet建议在整个过程中使用BigDecimal
,并在完成任何计算后进行四舍五入。)