Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从double到int的转换并不总是删除小数部分_Java - Fatal编程技术网

Java 从double到int的转换并不总是删除小数部分

Java 从double到int的转换并不总是删除小数部分,java,Java,我正在试验我在这里找到的代码 …因此,现在我正在寻找对该行为的解释???对该行为进行了详细解释我认为,将双精度转换为整数会导致使用“银行家四舍五入”对其进行四舍五入。许多十进制值不可能是双精度值。在使用之前,必须先将其压缩到最接近的双精度值 示例:16384.9999999999没有精确的双精度表示。最接近的两个值是16384.99999999963620219290828704833984375和16385.0。向下挤压会产生大约0.000000000003的差异,而向上挤压会产生0.0000

我正在试验我在这里找到的代码


…因此,现在我正在寻找对该行为的解释???

对该行为进行了详细解释

我认为,将双精度转换为整数会导致使用“银行家四舍五入”对其进行四舍五入。

许多十进制值不可能是双精度值。在使用之前,必须先将其压缩到最接近的双精度值


示例:
16384.9999999999
没有精确的双精度表示。最接近的两个值是
16384.99999999963620219290828704833984375
16385.0
。向下挤压会产生大约
0.000000000003
的差异,而向上挤压会产生
0.000000000001
的差异-向上挤压会产生更接近的值,所以这就是它的解释。

现在我相信这是一个错误

在Java规范(5.1.3)中,据说它使用“向零舍入”

否则,如果浮点数不是无穷大,则浮点数
值四舍五入为整数值V,使用IEEE 754向零四舍五入
向零模式取整(§4.2.3)。

向零取整(或截断,或从无穷远处取整)只是(引用维基):

q=truncate(y)=sgn(y)*地板(abs(y))=-sgn(y)*天花板(-(abs(y))


q是y的整数部分,没有小数位数。

有两种解释:

你遇到了一个问题,浮点运算不能像你想要的那样精确,所以它做得最好,但有时会产生奇怪的结果。这就是@Toomai的答案所暗示的,并且得到了@Ziyao Wei的答案的证实


还有,数字数学有时会“走错路”为了维护公平。这与@Lee Harrison的答案相对应,但显然更适用于C而不是Java。

您可以编写一个包含任意多个数字的文本
double
,但这并不意味着
double
值可以代表您编写的文本

去掉
int
强制转换,在将文本强制转换为
int
之前,可以更仔细地查看文本的
double
表示形式:

System.out.println(16383.999999999999);
System.out.println(16383.999868686868686999999999);
System.out.println(16384.999999999999);
System.out.println(16385.999999999999);
输出:

16383.999999999998
16383.99986868687
16385.0
16386.0
将这些值转换为int,您将看到:

16383
16383
16385
16386

也许你会惊讶于这样一个事实

System.out.println(131072.99999999999); // -> 131073 !!!
您不必将它转换为int

Java(以及其他语言)中的双重表示存在问题。系统不像我们人类那样使用“十进制”部分

这里详细解释了这一点:


但是,简言之,双值存储为几个部分,这些部分放在一起以获得最终结果(如图-1.23*10^-15所示)。并且对于这些给定的数字,您只有有限的空间。因此,最终您无法准确地表示Double.MAX\u值和Double.MIN\u值之间的每个数字。

当您有一个数字需要多一位时,这意味着可用的分数位数减少了一位,并且必须对其进行舍入

for(int i=4;i<=128*1024;i*=2) {
    double smallestFraction = Math.ulp((double) i-2);
    System.out.println(new BigDecimal(i) + " minus "+new BigDecimal(smallestFraction)+" is "+new BigDecimal(i-smallestFraction));
    System.out.println(new BigDecimal(i+1) + " minus "+new BigDecimal(smallestFraction)+" is "+new BigDecimal(i+1-smallestFraction));
}

没有错。双值表示实数,实数的数学告诉我们0,(9)=1

由于实数的表示,也存在一些问题,因此: 131070.9999999999表示为131070+0.9999999999
131072.999999999表示为131072+0。(9)IEEE标准有时会产生意想不到的结果。尽可能地用二进制写这些数字,记住比特宽度的限制,考虑IEEE如何将它们舍入,你会知道为什么会发生。谢谢所有的好答案!不幸的是,我只能接受一个……我只是搜索了,不是银行家的圆环。g“四舍五入到最近的偶数”正如凯恩所说,平局突破是一个更恰当的描述。当有人向我解释时,此人使用“银行家取整”作为一种“错误”取整的方式,试图保持统计准确性。然而,我认为我们在这一点上都是正确的。@ZiyaoWei-是的,从一个
到一个
int
的转换导致了trun阳离子,而不是四舍五入。事实上,这很容易在多行
.println((int)(小数))
行中看到。因此,不,这个答案是完全错误的。我引用了引用的站点:“当我们将浮点值分配给整型时,小数部分(如果有的话)会被删除(不是四舍五入)。”该网站确实解释了OP为什么会看到给定的行为。如果你能引用相关章节(并提供示例?),你得到我的投票。我今天已经学到了一些新东西…我还没有在网站上找到解释…我也没有对答案投反对票,因为给定的网站很有趣…@Downvoter:请解释原因;即使这是由机器表示double引起的,在某种意义上这仍然是一个bug,因为它不符合IEEE标准和Java语言规范。我刚刚意识到pgras写的数字太多了:他写了17个数字,超过了双精度限制。回答得好!现在我明白了,这是因为浮点表示法,整数部分用的数字越多,小数部分用的数字就越少…谢谢,现在我明白了问题所在lem与cast无关,而是与double的浮点表示有关。我的错误来自于我假设(int)(Math.random()+x)==x的原始代码,只有当x“足够小”时,它才是真的
System.out.println(131072.99999999999); // -> 131073 !!!
for(int i=4;i<=128*1024;i*=2) {
    double smallestFraction = Math.ulp((double) i-2);
    System.out.println(new BigDecimal(i) + " minus "+new BigDecimal(smallestFraction)+" is "+new BigDecimal(i-smallestFraction));
    System.out.println(new BigDecimal(i+1) + " minus "+new BigDecimal(smallestFraction)+" is "+new BigDecimal(i+1-smallestFraction));
}
4 minus 4.44089209850062616169452667236328125E-16 is 3.999999999999999555910790149937383830547332763671875
5 minus 4.44089209850062616169452667236328125E-16 is 5
8 minus 8.8817841970012523233890533447265625E-16 is 7.99999999999999911182158029987476766109466552734375
9 minus 8.8817841970012523233890533447265625E-16 is 9
16 minus 1.7763568394002504646778106689453125E-15 is 15.9999999999999982236431605997495353221893310546875
17 minus 1.7763568394002504646778106689453125E-15 is 17
32 minus 3.552713678800500929355621337890625E-15 is 31.999999999999996447286321199499070644378662109375
33 minus 3.552713678800500929355621337890625E-15 is 33
64 minus 7.10542735760100185871124267578125E-15 is 63.99999999999999289457264239899814128875732421875
65 minus 7.10542735760100185871124267578125E-15 is 65
128 minus 1.42108547152020037174224853515625E-14 is 127.9999999999999857891452847979962825775146484375
129 minus 1.42108547152020037174224853515625E-14 is 129
256 minus 2.8421709430404007434844970703125E-14 is 255.999999999999971578290569595992565155029296875
257 minus 2.8421709430404007434844970703125E-14 is 257
512 minus 5.684341886080801486968994140625E-14 is 511.99999999999994315658113919198513031005859375
513 minus 5.684341886080801486968994140625E-14 is 513
1024 minus 1.136868377216160297393798828125E-13 is 1023.9999999999998863131622783839702606201171875
1025 minus 1.136868377216160297393798828125E-13 is 1025
2048 minus 2.27373675443232059478759765625E-13 is 2047.999999999999772626324556767940521240234375
2049 minus 2.27373675443232059478759765625E-13 is 2049
4096 minus 4.5474735088646411895751953125E-13 is 4095.99999999999954525264911353588104248046875
4097 minus 4.5474735088646411895751953125E-13 is 4097
8192 minus 9.094947017729282379150390625E-13 is 8191.9999999999990905052982270717620849609375
8193 minus 9.094947017729282379150390625E-13 is 8193
16384 minus 1.818989403545856475830078125E-12 is 16383.999999999998181010596454143524169921875
16385 minus 1.818989403545856475830078125E-12 is 16385
32768 minus 3.63797880709171295166015625E-12 is 32767.99999999999636202119290828704833984375
32769 minus 3.63797880709171295166015625E-12 is 32769
65536 minus 7.2759576141834259033203125E-12 is 65535.9999999999927240423858165740966796875
65537 minus 7.2759576141834259033203125E-12 is 65537
131072 minus 1.4551915228366851806640625E-11 is 131071.999999999985448084771633148193359375
131073 minus 1.4551915228366851806640625E-11 is 131073