为什么toPrecision / toFixed不起作用?

时间:2019-07-01 14:05:01

标签: javascript typescript

请不要链接冗长的解释,为什么会这样。我已经知道了,我完全了解了,我了解IEEE-754,二进制文件,为什么出错以及JavaScript Rulez。我只想能够达到0.2 + 0.1 = 0.3,我不需要再次阅读为什么0.2 + 0.1 = 0.300 ... 04,我已经很认真地知道了

现在,我的问题:

我正在尝试避免JavaScript中Float的精度问题。好吧,确切地说,是在TypeScript中。

例如,我的问题通常在0.2 + 0.1 = 0.300 ... 004时出现。我尝试解决此问题,使用toFixed / toPrecision将数字转换为字符串,将它们存储为float,然后在需要计算时将字符串解析为float。但是这种解决方法不起作用,我时不时会得到相同的烦人数字。

我不明白为什么toFixed不起作用。在我看来,这没有任何意义:即使数字为0.300 ... 004,也应将其转换为字符串“ 0.3”,然后将其存储。谁能给我一些线索?

('increment'= 0.1时出现问题)

[更新:找到答案]

写完我自己的 toFixed 并遇到同样的问题后,我以为问题出在其他地方。它是:由于某种原因,打字稿被解析为浮在等号行上: this.amount = amount.toFixed(this.precision) 即使我自己写了toFixed,即使所有内容显然都是字符串类型。 因此,最终的解决方案是强制将其字符串化。因此,工作代码改用以下行: this.amount = amount.toFixed(this.precision).toString() 是的,将字符串转换为String,但现在可以正常工作。

这是我的(解决方案之前的)代码:

export class MytargetValueChangerComponent implements OnInit {
    @Input() amount = '1';
    @Input() unit = 'times';
    @Input() max: any = 1000000;
    @Input() min: any = 0;
    @Input() increment = '1';
    @Input() hideLeftArrow = false;
    @Input() hideRightArrow = false;

    @Output() valueChanged = new EventEmitter<number>();

    private precision: number;

    constructor() {
    }

    ngOnInit() {
        const increment = Number.parseFloat(this.increment);
        if (increment <= 0) {
            this.increment = '1';
        }

        this.calculatePrecision();
    }

    decrease() {
        let amount = Number.parseFloat(this.amount);
        const increment = Number.parseFloat(this.increment);
        const min = Number.parseFloat(this.min);

        if (amount > min) {
            amount -= increment;
            this.amount = amount.toFixed(this.precision);
        }

        this.valueChanged.emit(amount);
    }

    increase() {
        let amount = Number.parseFloat(this.amount);
        const increment = Number.parseFloat(this.increment);
        const max = Number.parseFloat(this.max);

        if (amount < max) {
            amount += increment;
            this.amount = amount.toFixed(this.precision);
        }

        this.valueChanged.emit(amount);
    }

    calculatePrecision() {
        this.precision = 0;
        let auxIncrement = Number.parseFloat(this.increment);
        while (auxIncrement < 1) {
            this.precision++;
            auxIncrement *= 10;
            console.log('mytarget-value-changer.component.tx.calculatePrecision in while loop'); // Security log, JIC infinite loop
        }
    }
}

0 个答案:

没有答案
相关问题