JavaScript は、数値が大きくなると、大きなINTを科学表記に変換します。これを防ぐにはどうすればよいですか?
translate科学表記法で座標を含む変換が発生すると、D3は例外をスローするようです。
JavaScript は、数値が大きくなると、大きなINTを科学表記に変換します。これを防ぐにはどうすればよいですか?
translate科学表記法で座標を含む変換が発生すると、D3は例外をスローするようです。
回答:
Number.toFixedがありますが、数値が1e21以上で最大精度が20の場合、科学表記法を使用します。それ以外の場合は、独自にロールできますが、乱雑になります。
function toFixed(x) {
if (Math.abs(x) < 1.0) {
var e = parseInt(x.toString().split('e-')[1]);
if (e) {
x *= Math.pow(10,e-1);
x = '0.' + (new Array(e)).join('0') + x.toString().substring(2);
}
} else {
var e = parseInt(x.toString().split('+')[1]);
if (e > 20) {
e -= 20;
x /= Math.pow(10,e);
x += (new Array(e+1)).join('0');
}
}
return x;
}
上記では、安価で簡単な文字列の繰り返し((new Array(n+1)).join(str))を使用しています。あなたはString.prototype.repeatロシアの農民乗算を使用して定義し、代わりにそれを使用することができます。
この回答は、科学的表記を使用せずに多数を表示するという質問のコンテキストにのみ適用する必要があります。何か他のもののために、あなたが使用する必要があるのBigIntなど、ライブラリをなBigNumber、LeemonのBigInt型、またはBigIntegerを。今後、新しいネイティブのBigInt(注:ないLeemonさん)が利用可能であるべきです。Chromiumとそれに基づくブラウザー(Chrome、新しいEdge [v79 +]、Brave)、Firefoxはすべてサポートされています。Safariのサポートが進行中です。
BigIntを使用する方法は次のとおりです。 BigInt(n).toString()
例:
注意より15-16桁(より具体的には、より大のJavaScript番号(ないのBigInt)などの任意の整数もし出力することを、しかし、Number.MAX_SAFE_INTEGER + 1[9,007,199,254,740,992])はJavaScriptのの番号タイプ(IEEE-754倍精度ので、丸められてもよいです浮動小数点)は、そのポイントを超えるすべての整数を正確に保持することはできません。とおりNumber.MAX_SAFE_INTEGER + 1、それは2の倍数で働いている、それはもう奇数を保持することはできませんので、(とsimiliarly、18,014,398,509,481,984でそれは...、16、その後、8そして、4の倍数で作業を開始)。
したがって、BigIntサポートに依存できる場合は、BigInt関数に渡す文字列として数値を出力します。
const n = BigInt("YourNumberHere");
例:
Math.abs。ヘッドアップをありがとう。
toFixed(Number.MAX_VALUE) == Number.MAX_VALUEその場合はtrueを返すはずですが、そうではありません...
これは古い質問ですが、最近アクティブになっているようです。MDN toLocaleString
const myNumb = 1000000000000000000000;
console.log( myNumb ); // 1e+21
console.log( myNumb.toLocaleString() ); // "1,000,000,000,000,000,000,000"
console.log( myNumb.toLocaleString('fullwide', {useGrouping:false}) ); // "1000000000000000000000"
オプションを使用して出力をフォーマットできます。
Number.toLocaleString()は小数点以下16桁で丸めるため、...
const myNumb = 586084736227728377283728272309128120398;
console.log( myNumb.toLocaleString('fullwide', { useGrouping: false }) );
...戻り値...
586084736227728400000000000000000000000
意図した結果で精度が重要な場合、これはおそらく望ましくありません。
js console.log( myNumb.toLocaleString('fullwide', { useGrouping: true, maximumSignificantDigits:6}) );
数が少なく、小数点以下の桁数がわかっている場合は、toFixedを使用してから正規表現を使用して末尾のゼロを削除できます。
Number(1e-7).toFixed(8).replace(/\.?0+$/,"") //0.000
(1000).toFixed(0).replace(/\.?0+$/,"") // 1, not 1000
もう1つの可能な解決策:
function toFix(i){
var str='';
do{
let a = i%10;
i=Math.trunc(i/10);
str = a+str;
}while(i>0)
return str;
}
Number.MAX_SAFE_INTEGERこの問題が発生する可能性が高い数より大きい数値。
これは、Number.prototype.toFixed任意の数で機能するメソッドの短い変形です:
Number.prototype.toFixedSpecial = function(n) {
var str = this.toFixed(n);
if (str.indexOf('e+') === -1)
return str;
// if number is in scientific notation, pick (b)ase and (p)ower
str = str.replace('.', '').split('e+').reduce(function(p, b) {
return p + Array(b - p.length + 2).join(0);
});
if (n > 0)
str += '.' + Array(n + 1).join(0);
return str;
};
console.log( 1e21.toFixedSpecial(2) ); // "1000000000000000000000.00"
console.log( 2.1e24.toFixedSpecial(0) ); // "2100000000000000000000000"
console.log( 1234567..toFixedSpecial(1) ); // "1234567.0"
console.log( 1234567.89.toFixedSpecial(3) ); // "1234567.890"
Number。最初のものをにキャストNumberすると、それらが完全に等しいことがわかります:jsfiddle.net/qd6hpnyx/1。反対投票を取り消すことができます:P
.0空の文字列に置き換える方が適切です。
console.log(2.2e307.toFixedSpecial(10))ます。つまり...後続のゼロがいくつか表示されます。とにかくこれが私が必要とするものに最も近いと思われるので賛成票を投じます。
次のソリューションは、非常に大きな数値と非常に小さな数値の自動指数形式をバイパスします。これはバグ修正を伴うoutisの解決策です:非常に小さな負の数では機能しませんでした。
function numberToString(num)
{
let numStr = String(num);
if (Math.abs(num) < 1.0)
{
let e = parseInt(num.toString().split('e-')[1]);
if (e)
{
let negative = num < 0;
if (negative) num *= -1
num *= Math.pow(10, e - 1);
numStr = '0.' + (new Array(e)).join('0') + num.toString().substring(2);
if (negative) numStr = "-" + numStr;
}
}
else
{
let e = parseInt(num.toString().split('+')[1]);
if (e > 20)
{
e -= 20;
num /= Math.pow(10, e);
numStr = num.toString() + (new Array(e + 1)).join('0');
}
}
return numStr;
}
// testing ...
console.log(numberToString(+0.0000000000000000001));
console.log(numberToString(-0.0000000000000000001));
console.log(numberToString(+314564649798762418795));
console.log(numberToString(-314564649798762418795));
他の人の答えはあなたに正確な数を与えません!
この関数は目的の数値を正確に計算し、JavaScriptで変更されないように文字列に返します。
数値結果が必要な場合は、関数の結果を1に乗算するだけです!
function toNonExponential(value) {
// if value is not a number try to convert it to number
if (typeof value !== "number") {
value = parseFloat(value);
// after convert, if value is not a number return empty string
if (isNaN(value)) {
return "";
}
}
var sign;
var e;
// if value is negative, save "-" in sign variable and calculate the absolute value
if (value < 0) {
sign = "-";
value = Math.abs(value);
}
else {
sign = "";
}
// if value is between 0 and 1
if (value < 1.0) {
// get e value
e = parseInt(value.toString().split('e-')[1]);
// if value is exponential convert it to non exponential
if (e) {
value *= Math.pow(10, e - 1);
value = '0.' + (new Array(e)).join('0') + value.toString().substring(2);
}
}
else {
// get e value
e = parseInt(value.toString().split('e+')[1]);
// if value is exponential convert it to non exponential
if (e) {
value /= Math.pow(10, e);
value += (new Array(e + 1)).join('0');
}
}
// if value has negative sign, add to it
return sign + value;
}
使用.toPrecision、.toFixedなどあなたがして、文字列に変換することにより、あなたの番号の桁数をカウントすることができ .toString、その時に見ています.length。
(2e64).toString()戻ります"2e+64"ので.length、役に立ちません。
これは、入力から値を取得するために使用したもので、17桁未満の数値を展開し、指数をx10 yに変換します
// e.g.
// niceNumber("1.24e+4") becomes
// 1.24x10 to the power of 4 [displayed in Superscript]
function niceNumber(num) {
try{
var sOut = num.toString();
if ( sOut.length >=17 || sOut.indexOf("e") > 0){
sOut=parseFloat(num).toPrecision(5)+"";
sOut = sOut.replace("e","x10<sup>")+"</sup>";
}
return sOut;
}
catch ( e) {
return num;
}
}
あなたは数をループして丸めを達成することができます
//指定されたインデックスでcharを置き換える機能
String.prototype.replaceAt=function(index, character) {
return this.substr(0, index) + character + this.substr(index+character.length);
}
//数値のループを開始します
var str = "123456789123456799.55";
var arr = str.split('.');
str = arr[0];
i = (str.length-1);
if(arr[1].length && Math.round(arr[1]/100)){
while(i>0){
var intVal = parseInt(str.charAt(i));
if(intVal == 9){
str = str.replaceAt(i,'0');
console.log(1,str)
}else{
str = str.replaceAt(i,(intVal+1).toString());
console.log(2,i,(intVal+1).toString(),str)
break;
}
i--;
}
}
数値ではなく文字列形式を使用してみましたが、これは機能するようでした。私はこれをChromeでテストしただけですが、それは普遍的であるべきです:
function removeExponent(s) {
var ie = s.indexOf('e');
if (ie != -1) {
if (s.charAt(ie + 1) == '-') {
// negative exponent, prepend with .0s
var n = s.substr(ie + 2).match(/[0-9]+/);
s = s.substr(2, ie - 2); // remove the leading '0.' and exponent chars
for (var i = 0; i < n; i++) {
s = '0' + s;
}
s = '.' + s;
} else {
// positive exponent, postpend with 0s
var n = s.substr(ie + 1).match(/[0-9]+/);
s = s.substr(0, ie); // strip off exponent chars
for (var i = 0; i < n; i++) {
s += '0';
}
}
}
return s;
}
同様の答えがいくつかあると思いますが、ここで私が思いついたことがあります
// If you're gonna tell me not to use 'with' I understand, just,
// it has no other purpose, ;( andthe code actually looks neater
// 'with' it but I will edit the answer if anyone insists
var commas = false;
function digit(number1, index1, base1) {
with (Math) {
return floor(number1/pow(base1, index1))%base1;
}
}
function digits(number1, base1) {
with (Math) {
o = "";
l = floor(log10(number1)/log10(base1));
for (var index1 = 0; index1 < l+1; index1++) {
o = digit(number1, index1, base1) + o;
if (commas && i%3==2 && i<l) {
o = "," + o;
}
}
return o;
}
}
// Test - this is the limit of accurate digits I think
console.log(1234567890123450);
注:これはJavaScript数学関数と同じくらい正確であり、forループの前の行でlog10ではなくlogを使用すると問題が発生します。1000をbase-10に000と書くので、人々はほとんどとにかくbase-10を使用するため、log10に変更しました。
これは非常に正確な解決策ではないかもしれませんが、私はそれがベース間で数値を正常に変換でき、コンマのオプションが付いていると言って誇りに思います!
あなたの質問:
number :0x68656c6c6f206f72656f
display:4.9299704811152646e+23
これを使用できます:https : //github.com/MikeMcl/bignumber.js
任意精度の10進数および非10進数の算術演算用のJavaScriptライブラリ。
このような:
let ten =new BigNumber('0x68656c6c6f206f72656f',16);
console.log(ten.toString(10));
display:492997048111526447310191
私はそれが何年後かを知っていますが、私は最近同様の問題に取り組んでいて、自分の解決策を投稿したいと思いました。現在受け入れられている答えは、指数部を0で埋め、正確な答えを見つけようとしますが、JSの浮動小数点精度の制限により、一般的に非常に大きな数では完全に正確ではありません。
これはで機能しMath.pow(2, 100)、正しい値1267650600228229401496703205376を返します。
function toFixed(x) {
var result = '';
var xStr = x.toString(10);
var digitCount = xStr.indexOf('e') === -1 ? xStr.length : (parseInt(xStr.substr(xStr.indexOf('e') + 1)) + 1);
for (var i = 1; i <= digitCount; i++) {
var mod = (x % Math.pow(10, i)).toString(10);
var exponent = (mod.indexOf('e') === -1) ? 0 : parseInt(mod.substr(mod.indexOf('e')+1));
if ((exponent === 0 && mod.length !== i) || (exponent > 0 && exponent !== i-1)) {
result = '0' + result;
}
else {
result = mod.charAt(0) + result;
}
}
return result;
}
console.log(toFixed(Math.pow(2,100))); // 1267650600228229401496703205376
toFixed(Number.MAX_VALUE) == Number.MAX_VALUE
function printInt(n) { return n.toPrecision(100).replace(/\..*/,""); }
いくつかの問題があります:
正規表現を破壊する。これには精度の問題はなく、コードも多くありません。
function toPlainString(num) {
return (''+num).replace(/(-?)(\d*)\.?(\d+)e([+-]\d+)/,
function(a,b,c,d,e) {
return e < 0
? b + '0.' + Array(1-e-c.length).join(0) + c + d
: b + c + d + Array(e-d.length+1).join(0);
});
}
console.log(toPlainString(12345e+12));
console.log(toPlainString(12345e+24));
console.log(toPlainString(-12345e+24));
console.log(toPlainString(12345e-12));
console.log(toPlainString(123e-12));
console.log(toPlainString(-123e-12));
console.log(toPlainString(-123.45e-56));
現在、科学表記法を解くためのネイティブ関数はありません。ただし、このためには独自の機能を作成する必要があります。
これが私のものです:
function dissolveExponentialNotation(number)
{
if(!Number.isFinite(number)) { return undefined; }
let text = number.toString();
let items = text.split('e');
if(items.length == 1) { return text; }
let significandText = items[0];
let exponent = parseInt(items[1]);
let characters = Array.from(significandText);
let minus = characters[0] == '-';
if(minus) { characters.splice(0, 1); }
let indexDot = characters.reduce((accumulator, character, index) =>
{
if(!accumulator.found) { if(character == '.') { accumulator.found = true; } else { accumulator.index++; } }
return accumulator;
}, { index: 0, found: false }).index;
characters.splice(indexDot, 1);
indexDot += exponent;
if(indexDot >= 0 && indexDot < characters.length - 1)
{
characters.splice(indexDot, 0, '.');
}
else if(indexDot < 0)
{
characters.unshift("0.", "0".repeat(-indexDot));
}
else
{
characters.push("0".repeat(indexDot - characters.length));
}
return (minus ? "-" : "") + characters.join("");
}
from-exponentialモジュールを使用できます。軽量で完全にテストされています。
import fromExponential from 'from-exponential';
fromExponential(1.123e-10); // => '0.0000000001123'
YourJS.fullNumberを使用することもできます。たとえばYourJS.fullNumber(Number.MAX_VALUE)、次のような結果になります。
179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
また、非常に少ない数でも機能します。 YourJS.fullNumber(Number.MIN_VALUE)これを返します:
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
この関数は常に有限数を文字列として返しますが、非有限数(例:NaNまたはInfinity)を次のように返します。undefined。
こちらのYourJSコンソールでテストできます。
使用できますnumber.toString(10.1):
console.log(Number.MAX_VALUE.toString(10.1));
注:これは現在Chromeでは機能しますが、Firefoxでは機能しません。仕様では、基数は整数でなければならないため、これは信頼性のない動作になります。
10.1 orまたは10orの使用は同等です。