الموضوع مبني على هذه المقالة http://bloodredsun.com/?p=320 و إضافة كلوجر من عندي.
مشكلة الأرقام العشرية إذا عرفت عن طريق المتغير double في لغات البرمجة:
في معظم لغات البرمجة تظهر مشكلة الأرقام العشرية إذا عرفت عن طريق المتغير double حيث أن إجراء العمليات الحسابية عليها لن يعود بأرقام دقيقة و ذلك نتيجة خطأ في إظهار بعض الأرقام بعد الفاصلة العشرية في صيغة IEEE-754
package com.bloodredsun;
public class DoubleOperation {
public static void main(String[] args) {
double t1 = 10.266d;
double t2 = 10.0d;
//Outputs 0.266
System.out.println(t1-t2);
double h1 = 100.266d;
double h2 = 100.0d;
//Outputs 0.26600000000000534
System.out.println(h1-h2);
}
}لذلك الحل في لغة مثل جافا عن طريق إستخدام مكتبة BigDecimal في java.math
package com.bloodredsun;
import java.math.BigDecimal;
public class BigDecimalOperation {
public static void main(String[] args) {
BigDecimal t1 = new BigDecimal("10.266");
BigDecimal t2 = new BigDecimal("10.0");
//Outputs 0.266
System.out.println(t1.subtract(t2));
BigDecimal h1 = new BigDecimal("100.266");
BigDecimal h2 = new BigDecimal("100.0");
//Outputs 0.266
System.out.println(h1.subtract(h2));
}
}لاحظ أنه يجب عليك إستخدام متغير نصي مع BigDecimal, كما يجب أن تلاحظ أن عملياتك الرياضية ستتم عن طريق إستدعء methods و ليس بإستخدام المعاملات الرياضية مباشرة.
لكن مع لغات مثل سكالا و كلوجر يمكنك التعامل مع ناتج BigDecimal مباشرة:
Scala:
package com.bloodredsun
object ScalaBigDecimalOperation {
def main (args: Array[String]) {
var t1 = BigDecimal("10.266")
var t2 = BigDecimal("10.0")
//Outputs 0.266
println(t1 - t2)
var h1 = BigDecimal("100.266")
var h2 = BigDecimal("100.0")
//Outputs 0.266
println(h1 - h2)
}
}Clojure:
((import (java.math.BigDecimal) (def t1 (BigDecimal. "10.266")) (def t2 (BigDecimal. "10.0")) (print (- t1 t2))
كما يمكنك تعريف دالة لتحويل الرقم المدخل لBigDecimal مباشرة:
(defn d[x](BigDecimal. (str x))) و بذلك يمكنك كتابة معادلتك مباشرة: user=> (- (d 10.002) (d 10.001)) 0.001
M
