2016-08-04 3 views
0

Я понимаю, что все числа в JavaScript являются плавающей запятой с двойной точностью. Как преобразовать double в float в JavaScript? Я понимаю точность потерь, но это терпимо.От double до float в JavaScript?

мне нужно изобразить стиль C чисел с плавающей точкой

+1

Один из способов будет использовать 'новый Float32Array ([yourNumber]) [0]', но это не поддерживается во всех браузерах. Зачем вам нужна потерянная точность? – Xufox

+2

Для чего вам нужен «плавать»? Контекст поможет нам понять, что вы собираетесь делать – qxz

+0

Мне нужно изобразить числа с плавающей запятой c style – marc

ответ

4

Это будет работать в современных двигателях:

function doubleToFloat (d) { 
    if (Float32Array) 
     return new Float32Array([d])[0]; 
} 

Обратите внимание, что тип данных результата по-прежнему номер (двойная точность), но это только использует 32 бита информации. Я добавил запасной вариант на случай, Float32Array не доступен:

function doubleToFloat (d) { 
    if (Float32Array) 
     return new Float32Array([ d ])[ 0 ]; 

    if (d === 0) 
     return d; 

    var sign = 2*(d >= 0) - 1; 
    var b = Math.abs(d).toString(2); 
    var decimalIndex = b.indexOf('.'); 
    var oneIndex = b.indexOf('1'); 
    var exponent, mantissa, round, result; 

    if(decimalIndex === -1) { 
     exponent = b.length - 1; 
     mantissa = b.substr(1, 23); 
     round = +(mantissa.length === 23 && b[24] === '1'); 
     result = sign*(parseInt('1' + mantissa, 2) + round)*Math.pow(2, exponent - mantissa.length); 
    } else if (decimalIndex === 1) { 
     exponent = 1 - oneIndex;  
     if (oneIndex === 0) { 
      mantissa = '1' + b.substr(2, 23); 
      round = +(mantissa.length === 24 && b[25] === '1'); 
      result = sign*(parseInt(mantissa, 2) + round)*Math.pow(2, 1 - mantissa.length); 
     } else { 
      mantissa = b.substr(oneIndex, 24); 
      round = +(mantissa.length === 24 && b[oneIndex + 24] === '1'); 
      result = sign*(parseInt(mantissa, 2) + round)*Math.pow(2, 1 + exponent - mantissa.length); 
     } 
    } else { 
     exponent = decimalIndex - 1; 
     mantissa = b.replace('.', '').substr(1, 23); 
     round = +(mantissa.length === 23 && b.replace('.', '')[24] === '1'); 
     result = sign*(parseInt('1' + mantissa, 2) + round)*Math.pow(2, decimalIndex - mantissa.length - 1); 
    } 

    if (exponent < -126) 
     return 0; 
    if (exponent > 127) 
     return sign*Infinity; 

    return result; 
} 
+0

это дает довольно плохую точность – marc

+6

@asehgal Да, разве это не то, что вы хотели? – Xufox

+0

Мне не нужна точность BAD. Я сказал, что желательно 32-битное представление, даже если оно связано с точностью потери. – marc

Смежные вопросы