簡體   English   中英

在沒有Float32Array的情況下將“float”轉換為Javascript中的字節

[英]Convert “float” to bytes in Javascript without Float32Array

好吧,所以我是一個相當討厭的情況,我無法訪問類型化的數組,如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];
};

對復制/粘貼中的任何錯誤表示道歉,代碼也省略了對字節序的任何處理,盡管它很容易添加。

感謝所有人發布建議,但我最終都是自己搞清楚,因為我想避免盡可能多地循環以獲得速度; 它仍然不是非常快,但它會做=)

見BinaryParser.encodeFloat 這里

您可以使用IEEE 754的JavaScript實現,如http://ysangkok.github.io/IEEE-754/index.xhtml中的實現 它使用Emscripten和gmp.js.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM