جافا سكريبت - تقصير الرقم إلى منزلتين عشريتين بدون تقريب
افترض أن لدي قيمة 15.7784514، أريد عرضها 15.77 بدون تقريب.
var num = parseFloat(15.7784514);
document.write(num.toFixed(1)+"<br />");
document.write(num.toFixed(2)+"<br />");
document.write(num.toFixed(3)+"<br />");
document.write(num.toFixed(10));
النتائج في -
15.8
15.78
15.778
15.7784514000
كيف أعرض 15.77؟
الإجابة رقم 1
حوّل الرقم إلى سلسلة، ووافق الرقم حتى العلامة العشرية الثانية:
function calc(theform) {
var num = theform.original.value, rounded = theform.rounded
var with2Decimals = num.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0]
rounded.value = with2Decimals
}<form onsubmit="return calc(this)">
Original number: <input name="original" type="text" onkeyup="calc(form)" onchange="calc(form)" />
<br />"Rounded" number: <input name="rounded" type="text" placeholder="readonly" readonly>
</form>طريقة toFixed تفشل في بعض الحالات على عكس toString، لذا كن حذرًا جدًا معها.
الإجابة رقم 2
function toFixed(num, fixed) {
var re = new RegExp('^-?\\d+(?:\.\\d{0,' + (fixed || -1) + '})?');
return num.toString().match(re)[0];
}
نظرًا لأن الحساب بالأعداد العشرية العائمة في جافاسكريبت سيكون دائمًا له حالات حافة، فإن الحل السابق سيكون دقيقًا في معظم الأحيان وهو ليس كافيًا. هناك بعض الحلول لذلك مثل num.toPrecision وBigDecimal.js وaccounting.js. ومع ذلك، أعتقد أن مجرد تحليل السلسلة سيكون الأبسط ودائمًا دقيقًا.
استنادًا إلى التحديث على التعبير النمطي المكتوب بشكل جيد من الإجابة المقبولة من قبل @Gumbo، ستعمل وظيفة toFixed الجديدة دائمًا كما هو متوقع.
إجابة قديمة، ليست دقيقة دائمًا:
قم بإنشاء دالتك الخاصة toFixed:
function toFixed(num, fixed) {
fixed = fixed || 0;
fixed = Math.pow(10, fixed);
return Math.floor(num * fixed) / fixed;
}
الإجابة رقم 3
حل آخر بخط واحد:
number = Math.trunc(number*100)/100
لقد استخدمت 100 لأنك تريد التقريب إلى الرقم الثاني، لكن الحل الأكثر مرونة سيكون :
number = Math.trunc(number*Math.pow(10, digits))/Math.pow(10, digits)
حيث أن الأرقام هي عدد الأرقام العشرية التي يجب الاحتفاظ بها.
انظر مواصفات Math.trunc للتفاصيل وتوافق المتصفح.
الإجابة رقم 4
اخترت كتابة هذا بدلاً من ذلك لإزالة الباقي يدويًا باستخدام السلاسل حتى لا أضطر للتعامل مع مشاكل الحساب التي تأتي مع الأرقام:
num = num.toString(); //If it's not already a String
num = num.slice(0, (num.indexOf("."))+3); //With 3 exposing the hundredths place
Number(num); //If you need it back as a Number
سيعطيك هذا "15.77" عندما يكون num=15.7784514;
الإجابة رقم 5
تحديث (يناير 2021)
هذا التحديث يتعلق بإضافة وظيفة تتحقق مما إذا كان الرقم بصيغة علمية، وإذا كان كذلك، تقوم بتحويله إلى صيغة عشرية. هنا أقترح هذا الخيار، ولكن يمكنك استخدام أي وظيفة أخرى تحقق نفس الهدف، وفقًا لاحتياجات تطبيقك:
function toFixed(x) {
if (Math.abs(x) < 1.0) {
let 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 {
let 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;
}
الآن فقط قم بتطبيق تلك الدالة على المعامل (هذا هو التغيير الوحيد مقارنة بالإجابة الأصلية):
function toFixedTrunc(x, n) {
x = toFixed(x)
// From here on the code is the same than the original answer
const v = (typeof x === 'string' ? x : x.toString()).split('.');
if (n <= 0) return v[0];
let f = v[1] || '';
if (f.length > n) return `${v[0]}.${f.substr(0,n)}`;
while (f.length < n) f += '0';
return `${v[0]}.${f}`
}
يتناول هذا الإصدار المحدّث أيضًا حالة تم ذكرها في تعليق:
toFixedTrunc(0.000000199, 2) => "0.00"
مرة أخرى، اختر ما يناسب احتياجات تطبيقك على أفضل وجه.
الإجابة الأصلية (أكتوبر 2017)
function toFixedTrunc(x, n) {
const v = (typeof x === 'string' ? x : x.toString()).split('.');
if (n <= 0) return v[0];
let f = v[1] || '';
if (f.length > n) return `${v[0]}.${f.substr(0,n)}`;
while (f.length < n) f += '0';
return `${v[0]}.${f}`
}
حيث يمكن أن يكون x إما رقمًا (يتم تحويله إلى سلسلة) أو سلسلة.
إليك بعض الاختبارات للقيمة n=2 (بما في ذلك الاختبار الذي طلبه صاحب المنشور):
0 => 0.00
0.01 => 0.01
0.5839 => 0.58
0.999 => 0.99
1.01 => 1.01
2 => 2.00
2.551 => 2.55
2.99999 => 2.99
4.27 => 4.27
15.7784514 => 15.77
123.5999 => 123.59
ولبعض القيم الأخرى لـ n:
15.001097 => 15.0010 (n=4)
0.000003298 => 0.0000032 (n=7)
0.000003298257899 => 0.000003298257 (n=12)
الإجابة رقم 6
parseInt أسرع من Math.floor
function floorFigure(figure, decimals){
if (!decimals) decimals = 2;
var d = Math.pow(10,decimals);
return (parseInt(figure*d)/d).toFixed(decimals);
};
floorFigure(123.5999) => "123.59"
floorFigure(123.5999, 3) => "123.599"
الإجابة رقم 7
num = 19.66752
f = num.toFixed(3).slice(0,-1)
alert(f)
سيُعيد هذا 19.66
الإجابة رقم 8
افعل هذا ببساطة
number = parseInt(number * 100)/100;
