转换“浮动”到Javascript中的字节没有Float32Array [英] Convert "float" to bytes in Javascript without Float32Array

查看:304
本文介绍了转换“浮动”到Javascript中的字节没有Float32Array的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我是一个相当烦人的情况,我无法访问像Float32Array这样的类型数组,但仍然需要能够将Javascript数字转换为字节。现在,我可以处理一个整数很好,但我不知道如何做一个浮点值。

我已经解决了这样做的问题其他的方式(字节到浮点数),但从浮点数转换为字节的文档是相当稀缺的,因为大多数语言只是让你读指针或有公共类来处理它。



理想情况下,我希望能够将浮点数转换为4字节和8字节的表示形式,并选择使用哪一个。然而,只需要一个数字并将其吐出为8字节的代码仍然非常棒,因为我可以自己拿出32位版本。

解决方案

好的,我真的知道了,所以我会分享我的解决方案的单精度和双精度。现在我不能保证他们是100%符合标准,但他们不需要循环,似乎工作得很好:

单精度(给定一个十进制值输出一个带有二进制表示的32位大端整数):

  function toFloat32(value){
var bytes = 0;
switch(value){
case Number.POSITIVE_INFINITY:bytes = 0x7F800000;打破;
case Number.NEGATIVE_INFINITY:bytes = 0xFF800000;打破;
case +0.0:bytes = 0x40000000;打破;
case -0.0:bytes = 0xC0000000;打破;
默认值:
if(Number.isNaN(value)){bytes = 0x7FC00000;打破;如果(值<= -0.0){
字节= 0x80000000;}

if
value = -value;


var exponent = Math.floor(Math.log(value)/ Math.log(2));
var significantand =((value / Math.pow(2,exponent))* 0x00800000) 0;

指数+ = 127;
if(exponent> = 0xFF){
exponent = 0xFF;
significand = 0;
} else if(exponent< 0)exponent = 0;

字节=字节| (指数<23);
字节=字节| (有意义&〜( - 1< 23));
break;
}
返回字节;
};

双精度(给定一个十进制值输出两个32位整数,二进制表示在big-endian如果((byteOffset + 8)> this.byteLength)函数toFloat64(value){


  
抛出无效的byteOffset:无法超出视图边界。;

var hiWord = 0,loWord = 0;
switch(value){
case Number.POSITIVE_INFINITY:hiWord = 0x7FF00000;打破;
case Number.NEGATIVE_INFINITY:hiWord = 0xFFF00000;打破;
case +0.0:hiWord = 0x40000000;打破;
case -0.0:hiWord = 0xC0000000;打破;
默认值:
if(Number.isNaN(value)){hiWord = 0x7FF80000;打破;如果(值<= -0.0){
hiWord = 0x80000000;}

if
value = -value;


var exponent = Math.floor(Math.log(value)/ Math.log(2));
var significantand = Math.floor((value / Math.pow(2,exponent))* Math.pow(2,52));

loWord = significant& 0xFFFFFFFF的;
significand / = Math.pow(2,32);

指数+ = 1023;
if(exponent> = 0x7FF){
exponent = 0x7FF;
significand = 0;
} else if(exponent< 0)exponent = 0;

hiWord = hiWord | (指数<< 20);
hiWord = hiWord | (有意义&〜( - 1< 20));
break;
}

return [hiWord,loWord];
};

在复制/粘贴过程中发生任何错误时,很容易添加。

感谢大家发表的建议,但是我最后主要是自己想出来的,因为我想尽可能地避免循环速度;它仍然不是很快,但它会做=)

Okay so I'm an a fairly annoying situation where I don't have access to typed arrays such as Float32Array, but still need to be able to convert a Javascript number into bytes. Now, an integer I can handle just fine, but I have no idea how to do it for a floating point value.

I've solved the problem of doing it the other way around (bytes into a float), but documentation on converting from float to bytes is pretty scarce, as most language just let you read the pointer or have common classes for handling it.

Ideally I'd like to be able to convert floats into both 4-byte and 8-byte representations, and choose which one to use. However, code that can simply take a number and spit it out as 8-bytes would still be great, as I can probably come up with the 32-bit version myself from there.

解决方案

Okay, so I actually figured it out, so I'll share my solution for single and double precision. Now I can't guarantee that they're 100% standards compliant, but they require no loops and seem to work just fine:

Single precision (given a decimal value outputs a single 32-bit big endian integer with the binary representation):

function toFloat32(value) {
    var bytes = 0;
    switch (value) {
        case Number.POSITIVE_INFINITY: bytes = 0x7F800000; break;
        case Number.NEGATIVE_INFINITY: bytes = 0xFF800000; break;
        case +0.0: bytes = 0x40000000; break;
        case -0.0: bytes = 0xC0000000; break;
        default:
            if (Number.isNaN(value)) { bytes = 0x7FC00000; break; }

            if (value <= -0.0) {
                bytes = 0x80000000;
                value = -value;
            }

            var exponent = Math.floor(Math.log(value) / Math.log(2));
            var significand = ((value / Math.pow(2, exponent)) * 0x00800000) | 0;

            exponent += 127;
            if (exponent >= 0xFF) {
                exponent = 0xFF;
                significand = 0;
            } else if (exponent < 0) exponent = 0;

            bytes = bytes | (exponent << 23);
            bytes = bytes | (significand & ~(-1 << 23));
        break;
    }
    return bytes;
};

Double precision (given a decimal value outputs two 32-bit integers with the binary representation in big-endian order):

function toFloat64(value) {
    if ((byteOffset + 8) > this.byteLength) 
        throw "Invalid byteOffset: Cannot write beyond view boundaries.";

    var hiWord = 0, loWord = 0;
    switch (value) {
        case Number.POSITIVE_INFINITY: hiWord = 0x7FF00000; break;
        case Number.NEGATIVE_INFINITY: hiWord = 0xFFF00000; break;
        case +0.0: hiWord = 0x40000000; break;
        case -0.0: hiWord = 0xC0000000; break;
        default:
            if (Number.isNaN(value)) { hiWord = 0x7FF80000; break; }

            if (value <= -0.0) {
                hiWord = 0x80000000;
                value = -value;
            }

            var exponent = Math.floor(Math.log(value) / Math.log(2));
            var significand = Math.floor((value / Math.pow(2, exponent)) * Math.pow(2, 52));

            loWord = significand & 0xFFFFFFFF;
            significand /= Math.pow(2, 32);

            exponent += 1023;
            if (exponent >= 0x7FF) {
                exponent = 0x7FF;
                significand = 0;
            } else if (exponent < 0) exponent = 0;

            hiWord = hiWord | (exponent << 20);
            hiWord = hiWord | (significand & ~(-1 << 20));
        break;
    }

    return [hiWord, loWord];
};

Apologies for any mistakes in copy/pasting, also the code ommits any handling of endianness, though it's fairly easy to add.

Thanks to everyone posting suggestions, but I ended up figuring out mostly on my own, as I wanted to avoid looping as much as possible for speed; it's still not exactly blazingly fast but it'll do =)

这篇关于转换“浮动”到Javascript中的字节没有Float32Array的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆