ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript の小数点以下の減算には、小数点以下の桁数の長いリストがあるのはなぜですか?

JavaScript の小数点以下の減算には、小数点以下の桁数の長いリストがあるのはなぜですか?

青灯夜游
青灯夜游オリジナル
2021-06-18 15:50:172517ブラウズ

理由: 整数型は自動的に整数型に変換されて計算され、10 進数型は直接 double 型に変換されて計算されます。また、double 型は 15 桁までの精度が必要です。 JavaScript で小数点を減算すると、小数点以下の長い文字列が生成されます。

JavaScript の小数点以下の減算には、小数点以下の桁数の長いリストがあるのはなぜですか?

このチュートリアルの動作環境: Windows7 システム、JavaScript バージョン 1.8.5、Dell G3 コンピューター。

JavaScript で小数点以下の減算を行うときに、小数点以下の長い文字列が表示される理由

<script>
var a=&#39;38.8&#39;;
var b=&#39;6.8&#39;;
alert(parseFloat(a)-parseFloat(b));
var a=134.22;
var b=6;
alert(a*b);
</script>

上記のコードでは、なぜ小数点以下の長い文字列が生成されるのでしょうか?より正確に言うと、それは可能ですが、その必要はありません。

これはデータ構造に関するもので、整数型は正の型に自動変換して計算し、十進型は直接倍精度型に変換して計算します。これはメモリ内で計算するときに必要です。コンピュータは 0 と 1 のみを認識することを知っておく必要があります。具体的な問題は浮動小数点の精度です。

  • float は小数点以下 7 桁まで正確です

  • double は小数点以下 15 桁まで正確です

javascript:document.write( (11.3-10.1).toFixed(2) )

toFixed() メソッドは、余分な小数点以下の桁を切り捨てるだけでなく、インターセプト位置の次の小数点以下の桁に基づいて丸めます。たとえば、値 10.739 を小数点以下 2 桁に切り捨てると、結果は 10.74 になります。値 10.732 を小数点以下 2 桁に切り捨てると、結果は 10.73 になります。

JavaScript では、小数点以下 0 ~ 20 桁の小数点のみを切り取ることができることに注意してください。

toFixed() メソッドはブラウザの上位バージョンでのみサポートされているため、使用する前にブラウザがこのメソッドをサポートしているかどうかを確認することをお勧めします。チェック コードは次のとおりです:

var varNumber = 22.234;
 
if (varNumber.toFixed)
{
varNumber = varNumber.toFixed(2);
}
else //浏览器不支持toFixed()就使用其他方法
{
var div = Math.pow(10,2);
varNumber = Math.round(varNumber * div) / div;
}

これは解決できますが、なぜこれほど多くの小数点を使用できるのかを尋ねたいと思います。

なぜこのような理解できない答えがあるのでしょうか?

#Google で調べたところ、これは JavaScript 浮動小数点演算のバグであることがわかりました。

例: 7*0.8 JavaScript は次のように計算します: 5.6000000000000005

オンラインでいくつかの解決策を見つけました。それは、いくつかの浮動小数点演算関数を書き直すことです。

これらのメソッドは、同じ問題に遭遇した友人の参考のために以下に抜粋されています:

プログラム コード

//除法函数,用来得到精确的除法结果
//说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
//调用:accDiv(arg1,arg2)
//返回值:arg1除以arg2的精确结果
 
function accDiv(arg1,arg2){
var t1=0,t2=0,r1,r2;
try{t1=arg1.toString().split(".")[1].length}catch(e){}
try{t2=arg2.toString().split(".")[1].length}catch(e){}
with(Math){
r1=Number(arg1.toString().replace(".",""))
r2=Number(arg2.toString().replace(".",""))
return (r1/r2)*pow(10,t2-t1);
}
}
//给Number类型增加一个div方法,调用起来更加方便。
Number.prototype.div = function (arg){
return accDiv(this, arg);
}
//乘法函数,用来得到精确的乘法结果
//说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
//调用:accMul(arg1,arg2)
//返回值:arg1乘以arg2的精确结果
function accMul(arg1,arg2)
{
var m=0,s1=arg1.toString(),s2=arg2.toString();
try{m+=s1.split(".")[1].length}catch(e){}
try{m+=s2.split(".")[1].length}catch(e){}
return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)
}
//给Number类型增加一个mul方法,调用起来更加方便。
Number.prototype.mul = function (arg){
return accMul(arg, this);
}
//加法函数,用来得到精确的加法结果
//说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
//调用:accAdd(arg1,arg2)
//返回值:arg1加上arg2的精确结果
function accAdd(arg1,arg2){
var r1,r2,m;
try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
m=Math.pow(10,Math.max(r1,r2))
return (arg1*m+arg2*m)/m
}
//给Number类型增加一个add方法,调用起来更加方便。
Number.prototype.add = function (arg){
return accAdd(arg,this);
}

これらの関数を使用したい場所に含めて、呼び出すだけです。それを計算するためです。

たとえば、7*0.8 を計算する場合、これを (7).mul(8) に変更します。

他の演算も同様で、より正確な結果を得ることができます。

[関連する推奨事項:

JavaScript 学習チュートリアル]

以上がJavaScript の小数点以下の減算には、小数点以下の桁数の長いリストがあるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。