还是精度丢失相关(臆测错了,已解决)

但0-2之间的2位小数*1000不会出现错误(不能算正常吧,只能算不出错,比如你取整)。
由于没做>2的测试,所以臆测错了。

    public static void main(String[] args) {
        for (int i = 0; i < 10000; i++) {
            double i0 = ((double) i) / 100;
            if (i0 * 1000 != i * 10) {
                System.out.println(i0 * 1000);
            }
        }
    }

从0-100可以看出,出现精度丢失的还是很多的。

至于为什么0-2的2位小数*1000都没错完全是正常现象,把*10、*100、*1000、*10000都试试就知道了

有可能被人搜到,简单描述一下精度丢失:

由于2进制只能表示少部分10进制小数,大部分都除不尽(自己想想为什么),所以在表示0.07时2进制是“0.000101111...”它真正的值是“0.07000000001”,当然电脑为了方便显示还是0.7,但当你用0.07*100时,真实的计算是“0.070...1*100",最后的数值进位了自然就无法忽略了。所以涉及小数计算的都有可能错一点点。(+=*甚至/都有可能)

精度损失和很多因素有关,比如二进制和十进制的转换,浮点数的累计误差。
和硬件、编译器、解释器的设计都有关。
先说硬件,同样一块cpu做双精度浮点运算,双精度是64bit的,但是x87单元内部精度是80位,所以中间运算精度损失小。但是isse2只有64位。而显卡甚至表面上64位,实际上64位都不到。
而编程语言使用什么设备(因为在早期,x87是一个独立的芯片,所以也叫设备,现在来看,就是不同的指令)都不同。
再比如,同样一个表达式,0.00000001+1000000000-1000000000,如果按照正确顺序计算,可能是0,因为前两个数字指数差别太大,0.00000001被忽略不计了。但是如果先算后面1000000000-1000000000=0,再算0.00000001+0,结果就是0.00000001。而编译器/解释器可能并不严格按照表达式顺序求值,作为一种优化手段来说。
所以这个完全不好说。

public class HelloWorld {
    public static void main(String []args) {
        System.out.println("float f = 0.0f;");
        for (int i = 0; i < 2000; i++) {
            String pre = "";
            if (i%100 ==0) pre = "0"; else if (i % 100 < 10) pre="0"; else pre = "";
        String s = "f = " + i / 100 + "." + pre + i % 100 + "f; System.out.println(f * 1000);";
        System.out.println(s);
        }
    }
}

用这个程序生成java代码
http://c.runoob.com/compile/10 这个网站上运行

图片说明

结果中并不都是整的。

用python 都是字符串计算不会错

Java中float和double是进行二进制的浮点型运算的。但会有精度丢失的问题。平常的还好,如果想要精确结果的话,就需要使用BigDecimal