ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

在没有Float32Array的情况下将“float”转换为Javascript中的字节

2019-09-28 18:36:11  阅读:101  来源: 互联网

标签:javascript floating-point type-conversion


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

我已经解决了相反的问题(将字节转换为浮点数),但是关于从float转换为字节的文档非常缺乏,因为大多数语言只是让您读取指针或具有处理它的公共类.

理想情况下,我希望能够将浮点数转换为4字节和8字节表示,并选择使用哪一个.但是,只需要一个数字并将其吐出为8字节的代码仍然很棒,因为我可能从那里自己想出32位版本.

解决方法:

好的,所以我实际想出来了,所以我将分享我的单精度和双精度的解决方案.现在我无法保证它们符合100%标准,但它们不需要循环,似乎工作得很好:

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

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;
};

双精度(给定十进制值以big-endian顺序输出两个32位整数和二进制表示):

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];
};

对复制/粘贴中的任何错误表示道歉,代码也省略了对字节序的任何处理,尽管它很容易添加.

感谢所有人发布建议,但我最终都是自己搞清楚,因为我想避免尽可能多地循环以获得速度;它仍然不是非常快,但它会做=)

标签:javascript,floating-point,type-conversion
来源: https://codeday.me/bug/20190928/1828533.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有