Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.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
C printf的最大数值信息密度_C_Json_Number Formatting - Fatal编程技术网

C printf的最大数值信息密度

C printf的最大数值信息密度,c,json,number-formatting,C,Json,Number Formatting,我的用例是将数字写入一个JSON文档,在这个文档中,大小最小化比非常小/非常大的数字的精度更重要。这些数字通常表示毫秒或米等常用单位,通常在[0.0011000]范围内 基本上我想设置一个最大字符长度。例如,如果限制为五个字符,则: from to 1234567 123e4 12345.6 12346 1234.56 1235 123.456 123.5 12.3456 12.35 1.23456 1.235 1.23450 1.235 1.23400

我的用例是将数字写入一个JSON文档,在这个文档中,大小最小化比非常小/非常大的数字的精度更重要。这些数字通常表示毫秒或米等常用单位,通常在[0.0011000]范围内

基本上我想设置一个最大字符长度。例如,如果限制为五个字符,则:

from      to

1234567   123e4
12345.6   12346
1234.56   1235
123.456   123.5
12.3456   12.35
1.23456   1.235
1.23450   1.235
1.23400   1.234
1.23000   1.23
1.20000   1.2
1.00000   1
0.11111   0.111
0.01111   0.011
0.00111   0.001
0.00011   11e-4
0.00001   1e-5
0.11111   0.111
0.01111   0.011
0.00111   0.001
0.00011   11e-4
0.00001   1e-5
这个测试用例似乎在一个长度约束中传递了最多的信息

当数字提升到范围[-99999]之外的幂时,它确实会失败,并且该范围将根据所施加的限制而变化。在这些罕见的情况下,可能这里的失败只是为了编写更长的字符串

这是一个理想的解决方案,尽管如果另一个解决方案比较接近,我可以不亲自实现它,可能是截断而不是舍入,并且不利用科学/指数表示法

编辑以下是
printf
%.3f
%.3g
%.4g
通过比较产生的内容():


对于将特定范围内的数字打包为最小无符号整数:

1) 减去可能的最小值。例如,如果您的数字可能在0.001到100000之间,并且特定的数字是123.456,则减去0.001得到123.455

2) 除以你关心的精度。例如,如果您关心千分之一,则除以0.001。在这种情况下,数字123.455变为123455

完成此操作并获得最小宽度的无符号整数后,将其转换为十六进制数字(或者可能是“基32位”)。对于上面的示例,0.001将变为0x00000000,123.456将变为0x0001E23F,100000将变为0x05F5E0FF

如果需要“可变精度”,可以添加第三步,将无符号整数值拆分为“值和移位计数”形式。例如:

    shift_count = 0;
    while(value > 0xFFF) {
        value = value >> 1;
        shift_count++;
    }

然后,您可以使用类似于
value=(value的东西进行连接。似乎您必须编写自己的转换例程。库函数可能会有所帮助


但是我会简单地使用
%.3g
%.4g
格式,去掉指数前多余的加号和前导零,就到此为止。这主要会留下一些可以优化的小数点。因为您非常关心JSON响应的大小,所以您可能会使用HTTP压缩,所以我怀疑这会造成很大的开销。

第一个例子当然最好用
123e4
来表达?@NPE你是对的——修改并包含了一些关于非常小/很大数量的潜在故障案例的信息。
printf
“%.4g”
足够接近吗?(在某些情况下太长了。)或者使用3位数字表示有效位,2位数字表示指数(偏置使指数
00
表示
-50
),嘿,普雷斯托,我发明了一种浮点数字表示法。说真的,如果你更关心简洁而不是精度,那么值得考虑这种表示法的一些变体。瞧,那些讨厌的
e
s没有浪费空间。@mafso,我编辑了我的答案来比较
“%.4g”
(以及
.3f
.4g
)使用我设计的场景。如果您知道您正在使用的数字的大致范围,您可以从这些示例输出中进行选择。谢谢。这看起来像。但是我实际上想要我在问题中给出的字符串形式。客户端是通过WebSocket接收JSON的浏览器。我不能要求客户端解压缩数字,尤其是因为不清楚哪些非结构化数据字段是数字,应该解包。如果我要走聪明的编码路线,我会使用类似于msgpack或protobuf或类似的东西。现在我只想知道,对于我使用标准C/C++描述(或接近它)的内容,是否有一个合理的API。
    shift_count = 0;
    while(value > 0xFFF) {
        value = value >> 1;
        shift_count++;
    }