2013-05-24 5 views
2

Я хочу преобразовать целое число в дробную часть числа с помощью javascript.Каков наиболее эффективный способ преобразования целого числа в дробную часть числа в javascript?

Например:

  • 10030 -> 0,10030

  • 123 -> 0,123

Я придумал два способа сделать это:

var convertIntegerPartToFractionalPart1 = function(integerPart) { 
    var fractionalPart = integerPart; 

    while(fractionalPart > 1) { 
     fractionalPart = fractionalPart/10; 
    } 
    return fractionalPart; 
}; 

var convertIntegerPartToFractionalPart2 = function(integerPart) { 
    return parseFloat('.' + integerPart); 
}; 

convertIntegerPa rtToFractionalPart1 не дает 100% точных результатов, например 132232 преобразуется в 0.13223200000000002. Однако convertIntegerPartToFractionalPart1 более чем в два раза быстрее, чем convertIntegerPartToFractionalPart2 под node.js на моем MacBook Pro. (1000000 прогонов convertIntegerPartToFractionalPart1 заняло 46 мс, 1000000 прогонов convertIntegerPartToFractionalPart2 заняло 96 мс)

Есть ли лучший способ сделать это?

+1

Наблюдение в методе 1 будет ясно после прочтения [Что каждый ученый должен знать о арифметики с плавающей точкой] (http://www.cse.msu.edu/~cse320/Documents/ FloatingPoint.pdf) – devnull

+0

Вы можете сделать что-то вроде: 'factionalPart = integerPart/(10^ceil (log10 (integerPart)))' [обратите внимание, что это псевдокод, так как вам придется выполнять свою собственную функцию log10 на основе естественного входа в javascrit и использовать 'Math.' для вызовов lib]. Я подозреваю, в конце концов, это будет не так хорошо, как ваш вариант 1. Таким образом, мой голос будет вариантом 1, если вам больше нужно время и вариант 2, если вы заботитесь о том, чтобы результат был совершенным. :) – lurker

+0

@devnull Спасибо за ссылку. – alexbirkett

ответ

2

В первую очередь я не хотел отвечать, поскольку решение Pointys кажется намного более элегантным.

Но после выполнения Jsperf оказалось, что решение Math было около 70% медленнее для меня на хроме.

function cnvrt3 (n) { 
    return n/Math.pow(10,(""+n).length) 
} 
cnvrt3(132232)//0.132232 

Так Херес же с помощью литья, чтобы определить мощность десяти

Примечание благодаря floating point точности 0.132232 не очень 0.132232.Хотя, скорее всего, значение, которое вы ищете

+0

Это отличная идея :-) – Pointy

+0

@Pointy Thanks =) – C5H8NNaO4

+0

Это самый быстрый из всех 1000000 пробегов 21ms! – alexbirkett

2

Попробуйте это:

function cvt3(n) { 
    return n/Math.pow(10, Math.ceil(Math.log(n)/Math.LN10)); 
} 

Это все еще будет возможно, что результат не будет точно, в связи с характером бинарной плавающей точкой (я думаю). Но сделать одно подразделение может помочь. Для меньших чисел ваша итерация может быть такой же хорошей и быстрой.

console.log(cvt3(132232)); // 0.132232 

редактировать версия г-глутамат натрия быстрее!

+0

Вы всегда должны делиться на целое число, поэтому я не думаю, что это была бы сигнальная проблема. Обычно вы действительно видите проблемы, в которых числа с плавающей запятой делятся или умножаются много раз, поэтому (по большей части) это не должно быть проблемой. –

+0

@ Qantas94Heavy и, тем не менее, итеративный метод «Разделить на 10» вводит артефакт. – Pointy

+0

@ Qantas94Heavy ... но, возможно, это потому, что 10 делится на нецелое число. – Pointy

0

Вы не будете поддерживать числа с конечными нулями, как в вашем примере:

10030 ->0.10030 

но вы можете предварять точку в начале строки:

'.'+String(10030)-> '.10030' 
+0

не будет '+ ("." + 10030)' достаточно? – C5H8NNaO4

0

Вот лучший подход к так это:

Demo Here

function ab() { 
     var a = 566123; 

     var len = a.toString().length; 
     var decimalPoints = 1; 

     for (var i = 0; i < len; i++) { 
      decimalPoints = decimalPoints * 10; 
     } 

     var number = parseInt(a)/decimalPoints; 
     alert(number); 
    } 
+0

Добавил ваш фрагмент к [JSPerf] (http://jsperf.com/cast-vs-math-int-to-frac) – C5H8NNaO4

+0

спасибо большое. Я не знал об этом. Для чего это? – Sudarshan

+0

Добро пожаловать =) Это для яваскрипта тестирования производительности – C5H8NNaO4