减少双值时出现奇怪的错误

时间:2015-07-10 09:35:29

标签: java user-interface

在开发应用程序时,我发现了一个严重的错误。但首先是一些细节:我想在GUI上显示温度。温度是双倍的值。用户应该能够增加/降低温度。目标是模拟加热装置的加热/温度阀。除了具有随机值之外,用户还应该能够使用GUI增加/减少此值。基本上,该值在启动时初始化为20.1(只是我在开头设置的随机值)。

当我试图降低温度时,我注意到了一种奇怪的行为。在递增时,一切都有效。但降低温度(按步骤1)会产生以下结果:20.1,19.1,18.1,17.1,16.1,然后是15.100000000000001,14.100000000000001等。

原因是什么? 当使用以.1结尾的值时,会发生错误。因此,尝试使用22.1或31.1的基值时,它没有任何区别。

错误总是在16.1到15之间发生变化......

每次都可以重复使用。我已经写了一个测试应用程序,请随意尝试:

package devices;

import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Test extends JFrame {

/**
 * the temperature
 */
private Double temp = 20.1;
private JPanel contentPane;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                Test frame = new Test();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public Test() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 271, 152);
    contentPane = new JPanel();
    setContentPane(contentPane);
    contentPane.setLayout(null);

    final JLabel lblNewLabel = new JLabel("");
    lblNewLabel.setBounds(10, 11, 235, 56);
    lblNewLabel.setFont(new Font("Tahoma", Font.PLAIN, 19));
    lblNewLabel.setText(String.valueOf(temp));
    contentPane.add(lblNewLabel);

    JButton btnNewButton_1 = new JButton("Increase");
    btnNewButton_1.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            temp = temp + 1;
            lblNewLabel.setText(String.valueOf(temp));
        }
    });
    btnNewButton_1.setBounds(10, 78, 101, 23);
    contentPane.add(btnNewButton_1);

    JButton btnNewButton = new JButton("Decrease");
    btnNewButton.setBounds(137, 78, 108, 23);
    btnNewButton.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            temp = temp - 1;
            lblNewLabel.setText(String.valueOf(temp));
        }
    });
    contentPane.add(btnNewButton);
}

}

提前问候和致谢,

儒略

3 个答案:

答案 0 :(得分:1)

0.1不是二进制的整数,因此您不能始终按十分之一步进。示例here。如果十分之一是您需要的最佳分辨率,请将它们存储为int并手动显示:

(temp/10).toString() +"."+(temp℅10).toString()

例如,这就是Turbo Pascal为金钱所做的事情。

答案 1 :(得分:0)

Double和其他默认浮点表示,是无限范围os值的离散表示(两个整数之间存在无限值:1,1.1,1.11,1.11,... 2)。

因此,许多价值观都没有确切的代表性。

您应该将数字四舍五入到所需的精度。

答案 2 :(得分:0)

见这个

[http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html]

然后使用BigDecimal而不是Double。