【问题标题】:Java: Possible Loss of Precision When Using `Math.sin()`Java:使用“Math.sin()”时可能会丢失精度
【发布时间】:2016-04-08 16:53:14
【问题描述】:

我是 Java 新手。我想打印出每 15 度间隔的 sincostan 值。

public class W3Aufgabe5 {
    public static void main(String[] args) {

        System.out.printf("%6s%6s%6s%6s%n", "Angle", "Sin", "Cos", "Tan");
        System.out.println("------------------------");

        for (float angle = 0; angle <= 180; angle += 15) {

            float sin = Math.sin(Math.toRadians(angle));
            float cos = Math.cos(Math.toRadians(angle));
            float tan = Math.tan(Math.toRadians(angle));

            System.out.printf("%6d%6d%6d%6d%n", angle, sin, cos, tan);
        }
    }
}

对于每个Math.x() 行,编译器都会打印

错误:可能会丢失精度
必需:浮动
发现:双

我真的不明白。为什么即使我一直在使用float,它也需要double

【问题讨论】:

  • 为什么会有浮罪?除非你有真正的理由使用浮点数,否则只使用双精度,例如。图像处理或图形。

标签: java math trigonometry


【解决方案1】:

三角法sincostantoRadians都接受double作为参数并返回double。没有接受floats 并返回floats 的重载。将float 传递给期望double 的方法是合法的;它将被隐式加宽。但是,当您将结果分配给floats 时,您不能将double 隐式缩小为float

如果需要,您可以将结果显式转换为 float,但使用 double 可以获得更好的精度,因此将您的 sincostan 变量声明为 doubles。

另外,格式说明符d 表示整数值,而不是浮点值。使用format specifier f instead of d。打印时,您可能还希望在值之间放置一些间距。

【讨论】:

  • 谢谢,这行得通。我认为格式说明符 fd 与 float 和 double 有关
  • 不,f 代表“定点”(作为格式),e 代表指数或工程,g 选择最合适的。请参阅 C printf 格式字符串,它也是 Java printf 函数的基础。
【解决方案2】:

如果您查看API documentation,您会发现 trig 方法都将返回双精度数。除非您真的需要浮点数,否则最好的选择是使用双打。您会失去精度,因为您必须将双返回值强制转换为浮点数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-05
    相关资源
    最近更新 更多