Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在javascript中将浮点数转换为字符串_Javascript_Byte_Three.js_Chars - Fatal编程技术网

在javascript中将浮点数转换为字符串

在javascript中将浮点数转换为字符串,javascript,byte,three.js,chars,Javascript,Byte,Three.js,Chars,好的,我想将一个包含3.Vector3的数组高效地保存到本地存储。由于javascript使用字符串工作,因此我希望使用最有效的比特率将32位浮点转换为字符串。i、 理想情况下,32位浮点=4*8位,这在C中很容易实现++ 问题似乎是第一个Javascript字符串是UTF,其中包含一些填充 其次,我当前使用的代码0被转换为“”,然后被省略,使得转换后的字节长度不可靠 String.fromCharCode(0)='' 塔克斯 诀窍在于获取可打印的无符号8位整数的字符串值。我发现如果你的8位数

好的,我想将一个包含3.Vector3的数组高效地保存到本地存储。由于javascript使用字符串工作,因此我希望使用最有效的比特率将32位浮点转换为字符串。i、 理想情况下,32位浮点=4*8位,这在C中很容易实现++

问题似乎是第一个Javascript字符串是UTF,其中包含一些填充

其次,我当前使用的代码0被转换为“”,然后被省略,使得转换后的字节长度不可靠

String.fromCharCode(0)=''


塔克斯

诀窍在于获取可打印的无符号8位整数的字符串值。我发现如果你的8位数字太小或太大(超出了ASCII值的“面包和黄油”范围),你最终会得到无法打印的东西。因此,我们不必使用来自浮点的字节的四个ASCII值来创建长度为4的字符串,而可以使用来自浮点的4位值来创建长度为8的字符串,并将这些值偏移到可打印范围(+32)中。以下是我的解决方案:

var offset = 33;

var float2str = function(num){
    var view = new DataView(new ArrayBuffer(4));
    view.setFloat32(0,num);

    var fourbits = [];
    for ( var i = 0; i < 4; i++ ){
        // split each byte into two 4-bit values
        fourbits.push(view.getUint8(0) >> 4);
        fourbits.push(view.getUint8(0) & 15);
    }

    for ( var i = 0; i < 8; i++ ){
        // build a string with offset four-bit values
        fourbits[i] = String.fromCharCode(offset+fourbits[i]);
    }
    return fourbits.join('');

};

var str2float = function(str){
    var bytestream = str;
    var view = new DataView(new ArrayBuffer(4));

    for(var i = 0; i < 4; i++){
        // re-convert the characters into bytes.
        view.setUint8(i, ((bytestream[i*2].charCodeAt() - offset) << 4) + bytestream[i*2+1].charCodeAt() - offset);
    }

    return view.getFloat32(0);
};

console.log(float2str('2.251')); // "%!\"!\"!'#"
console.log(str2float(float2str('2.251'))); // 2.250999927520752
var offset=33;
var float2str=函数(num){
var视图=新的数据视图(新的ArrayBuffer(4));
view.setFloat32(0,num);
var四位=[];
对于(变量i=0;i<4;i++){
//将每个字节拆分为两个4位值
四位推送(view.getUint8(0)>>4);
四位推送(view.getUint8(0)和15);
}
对于(变量i=0;i<8;i++){
//使用偏移量四位值构建字符串
四位[i]=字符串.fromCharCode(偏移量+四位[i]);
}
返回四位。join(“”);
};
var str2float=函数(str){
var bytestream=str;
var视图=新的数据视图(新的ArrayBuffer(4));
对于(变量i=0;i<4;i++){
//将字符重新转换为字节。

view.setUint8(i,((bytestream[i*2].charCodeAt()-offset)技巧在于获取可打印的无符号8位整数的字符串值。我发现如果8位数字太小或太大(超出ASCII值的“面包和黄油”范围)您将得到一些不可打印的内容。因此,我们不必使用浮点中字节的四个ASCII值创建长度为4的字符串,而可以使用长度为8的字符串,使用浮点中的4位值,并将这些值偏移到可打印范围(+32)。以下是我的解决方案:

var offset = 33;

var float2str = function(num){
    var view = new DataView(new ArrayBuffer(4));
    view.setFloat32(0,num);

    var fourbits = [];
    for ( var i = 0; i < 4; i++ ){
        // split each byte into two 4-bit values
        fourbits.push(view.getUint8(0) >> 4);
        fourbits.push(view.getUint8(0) & 15);
    }

    for ( var i = 0; i < 8; i++ ){
        // build a string with offset four-bit values
        fourbits[i] = String.fromCharCode(offset+fourbits[i]);
    }
    return fourbits.join('');

};

var str2float = function(str){
    var bytestream = str;
    var view = new DataView(new ArrayBuffer(4));

    for(var i = 0; i < 4; i++){
        // re-convert the characters into bytes.
        view.setUint8(i, ((bytestream[i*2].charCodeAt() - offset) << 4) + bytestream[i*2+1].charCodeAt() - offset);
    }

    return view.getFloat32(0);
};

console.log(float2str('2.251')); // "%!\"!\"!'#"
console.log(str2float(float2str('2.251'))); // 2.250999927520752
var offset=33;
var float2str=函数(num){
var视图=新的数据视图(新的ArrayBuffer(4));
view.setFloat32(0,num);
var四位=[];
对于(变量i=0;i<4;i++){
//将每个字节拆分为两个4位值
四位推送(view.getUint8(0)>>4);
四位推送(view.getUint8(0)和15);
}
对于(变量i=0;i<8;i++){
//使用偏移量四位值构建字符串
四位[i]=字符串.fromCharCode(偏移量+四位[i]);
}
返回四位。join(“”);
};
var str2float=函数(str){
var bytestream=str;
var视图=新的数据视图(新的ArrayBuffer(4));
对于(变量i=0;i<4;i++){
//将字符重新转换为字节。

view.setUint8(i,((bytestream[i*2].charCodeAt()-offset))使用base64编码。它将一次将6位转换为可打印的ASCII字符(在UTF-8中相同)。因此,一个浮点实际上需要5.33字节(分数是可用的,也就是说,只要将数组作为一个整体进行编码,而不是作为单个浮点进行编码,分数就不是6个字节),但这仍然可以节省一些空间


这里有一个函数(不是我的)可以直接从
ArrayBuffer
转换为base64字符串:

使用base64编码。它一次将6位转换为可打印的ASCII字符(在UTF-8中也是如此)。因此,一个浮点实际上需要5.33字节(分数是可用的,也就是说,只要将数组作为一个整体进行编码,而不是作为单个浮点进行编码,分数就不是6个字节),但这仍然可以节省一些空间


这是一个函数(不是我的)要直接从
ArrayBuffer
转换为base64字符串:

为什么不能将浮点数简单地存储为浮点数?我的意思是,据我所知,localStorage应该能够高效地存储所有JavaScript对象,而不管它们的类型如何。你到底从哪里听说JavaScript只与字符串一起工作?我想他是说localStorage可以工作是的,我相信你必须用本地存储来存储一个字符串。如果你存储一个像Pi-3.142这样的数字……每个数字都存储为一个字符,这是非常不合理的。为什么你不能简单地将浮点数存储为浮点数呢?我的意思是,据我所知,本地存储应该能够有效地存储所有JavaScript对象,而不管它们的大小ir类型。你到底从哪里听说javascript只对字符串起作用?我想他是说localStorage只对字符串起作用。是的,我相信你必须用本地存储来存储字符串。如果你存储一个像Pi-3.142这样的数字……每个数字存储为一个字符,这个字符在这里作为偏移量使用时非常不方便我们的输出字符串中没有空格,但是
32
也可以。因为最初的目标是有效地打包浮点,每个浮点使用8个字节会破坏这一目的,因为在许多实际情况下,常规字符串表示会更短。(根据Wikipedia,32位浮点对6-9位有效数字具有精度,这可能转化为字符串的11字节(小数点和负数相加)的最坏情况,但我猜典型数字/足够精度最有可能用更少的数字实现(例如2595e-8=7))。在本地存储中存储大量数字的最佳方法可能是简单地创建包含数字的JSON字符串,并在将其保存到本地存储之前在其上运行BZip。嗨,Jason,感谢您的帮助,虽然您的代码确实有效,但它包含32位到8位的16位字符,最终为128位/浮点。我想