我正在尝试将随机双精度转换为长整数而不进行舍入或截断。 首先,我将double更改为一个字符串,知道有多少小数位,然后我将值更改为long。 我的问题是,最后一个小数位的数字并不总是正确的,我不知道原因以及如何更改它。 这是代码:
double z=(double) myRandom(1, 20);
long test;
String s = Double.toString(z);
test=(long) (Math.pow(10, s.length()-s.indexOf(".")-1)*z);
System.out.println("z: "+z);
System.out.println("double converted to long: "+test);
这就是输出:
d:19.625014811604743
双转换为长:19625014811604744
d:9.143326452202839
双转换为长:9143326452202838
d:5.8964228376511105
双转换为长:58964228376511104
d:15.045936360299917
double double to long:15045936360299918
d:14.147950026532694
双转换为长:14147950026532694
答案 0 :(得分:3)
编辑您当前的实施:
double z=(double) myRandom(1, 20);
String s = Double.toString(z); //convert to string (edited thanks to comments)
s = s.replaceAll(".", ""); //remove the period
long test = Long.parseLong(s); //convert to long
或者,如果您只是想要随机Long
,我建议您改用Random.nextLong()
。
答案 1 :(得分:2)
如果你的目标是获得一个随机长号,那么我强烈建议使用Random.nextLong()代替。
答案 2 :(得分:0)
test=(long) (Math.pow(10, s.length()-s.indexOf(".")-1)*z);
在算术中弄乱你的双倍,尝试这样的事情:
public long convertDoubleToLong(double d){
String str = Double.toString(d);
return Long.parseLong(str.replace(".", ""));
}
答案 3 :(得分:0)
你可以这样做......
double x = 19.625014811604743;
while(x % 1 != 0) x *= 10;
long y = (long) x;
System.out.println("x: "+ x + " y: "+ y);
答案 4 :(得分:0)
其他答案已经指出了如何解决这个问题,但你的另一个问题是为什么它会发生。答案就是浮点错误。
浮点数由三个主要部分组成:符号(+或 - ),尾数和指数。基本上,该数字基本上表示为(sign) (mantissa) * 2^(exponent)
(但不完全是 - 请参阅下面的链接)。可以想象,并非所有数字都适合这种表现形式;有些必须近似。典型的例子是十分之一,它在二进制中具有无限重复序列,因此必须以双精度近似。
在高值时 - 大于尾数的那些可以重复 - 有一些整数无法准确表示。这发生在2 ^ 53;任何大于此的数字都必须近似,你提到的数字就是这样的例子。
您甚至不需要Math.pow
来证明这一点;文字会很好。
public static void main(String[] args) {
double d1 = 19.625014811604743;
double d2 = 19625014811604743.0;
System.out.println(d1);
System.out.println(d2);
}
这将打印:
19.625014811604743
1.9625014811604744E16
注意第二个值末尾的4。 19625014811604744是距离19625014811604743最近的数字,可以表示为双数。
相关阅读:
答案 5 :(得分:0)
如果要通过除去小数部分来舍入一个双数,可以看到以下示例:
Long doubleToLong(double dAmount) {
return (long) (int) dAmount;
}