Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
畅游知识海洋
json
提交
b7e0c129
J
json
项目概览
畅游知识海洋
/
json
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
json
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
GitCode(gitcode.net)2024年7月9日维护升级公告
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
b7e0c129
编写于
12月 07, 2016
作者:
N
Niels Lohmann
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
✨
CBOR support for half-precision floats
上级
17c9b17a
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
62 addition
and
10 deletion
+62
-10
src/json.hpp
src/json.hpp
+24
-1
src/json.hpp.re2c
src/json.hpp.re2c
+30
-1
test/src/unit-cbor.cpp
test/src/unit-cbor.cpp
+8
-8
未找到文件。
src/json.hpp
浏览文件 @
b7e0c129
...
...
@@ -34,7 +34,7 @@ SOFTWARE.
#include <cassert> // assert
#include <cctype> // isdigit
#include <ciso646> // and, not, or
#include <cmath> // isfinite, signbit
#include <cmath> // isfinite,
ldexp,
signbit
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
#include <cstdint> // int64_t, uint64_t
#include <cstdlib> // strtod, strtof, strtold, strtoul
...
...
@@ -7169,6 +7169,29 @@ class basic_json
{
return
value_t
::
null
;
}
else
if
(
v
[
current_idx
]
==
0xf9
)
// Half-Precision Float
{
idx
+=
2
;
// skip two content bytes
// code from RFC 7049, Appendix D
const
int
half
=
(
v
[
current_idx
+
1
]
<<
8
)
+
v
[
current_idx
+
2
];
const
int
exp
=
(
half
>>
10
)
&
0x1f
;
const
int
mant
=
half
&
0x3ff
;
double
val
;
if
(
exp
==
0
)
{
val
=
std
::
ldexp
(
mant
,
-
24
);
}
else
if
(
exp
!=
31
)
{
val
=
std
::
ldexp
(
mant
+
1024
,
exp
-
25
);
}
else
{
val
=
mant
==
0
?
INFINITY
:
NAN
;
}
return
half
&
0x8000
?
-
val
:
val
;
}
else
if
(
v
[
current_idx
]
==
0xfa
)
// Single-Precision Float
{
// copy bytes in reverse order into the float variable
...
...
src/json.hpp.re2c
浏览文件 @
b7e0c129
...
...
@@ -34,7 +34,7 @@ SOFTWARE.
#include <cassert> // assert
#include <cctype> // isdigit
#include <ciso646> // and, not, or
#include <cmath> // isfinite, signbit
#include <cmath> // isfinite,
ldexp,
signbit
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
#include <cstdint> // int64_t, uint64_t
#include <cstdlib> // strtod, strtof, strtold, strtoul
...
...
@@ -7169,6 +7169,35 @@ class basic_json
{
return value_t::null;
}
else if (v[current_idx] == 0xf9) // Half-Precision Float
{
idx += 2; // skip two content bytes
// code from RFC 7049, Appendix D, Figure 3:
// As half-precision floating-point numbers were only added to IEEE
// 754 in 2008, today's programming platforms often still only have
// limited support for them. It is very easy to include at least
// decoding support for them even without such support. An example
// of a small decoder for half-precision floating-point numbers in
// the C language is shown in Figure 3.
const int half = (v[current_idx + 1] << 8) + v[current_idx + 2];
const int exp = (half >> 10) & 0x1f;
const int mant = half & 0x3ff;
double val;
if (exp == 0)
{
val = std::ldexp(mant, -24);
}
else if (exp != 31)
{
val = std::ldexp(mant + 1024, exp - 25);
}
else
{
val = mant == 0 ? INFINITY : NAN;
}
return half & 0x8000 ? -val : val;
}
else if (v[current_idx] == 0xfa) // Single-Precision Float
{
// copy bytes in reverse order into the float variable
...
...
test/src/unit-cbor.cpp
浏览文件 @
b7e0c129
...
...
@@ -1102,26 +1102,26 @@ TEST_CASE("examples from RFC 7049 Appendix A")
// half-precision float
//CHECK(json::to_cbor(json::parse("0.0")) == std::vector<uint8_t>({0xf9, 0x00, 0x00}));
//
CHECK(json::parse("0.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x00, 0x00})));
CHECK
(
json
::
parse
(
"0.0"
)
==
json
::
from_cbor
(
std
::
vector
<
uint8_t
>
({
0xf9
,
0x00
,
0x00
})));
// half-precision float
//CHECK(json::to_cbor(json::parse("-0.0")) == std::vector<uint8_t>({0xf9, 0x80, 0x00}));
//
CHECK(json::parse("-0.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x80, 0x00})));
CHECK
(
json
::
parse
(
"-0.0"
)
==
json
::
from_cbor
(
std
::
vector
<
uint8_t
>
({
0xf9
,
0x80
,
0x00
})));
// half-precision float
//CHECK(json::to_cbor(json::parse("1.0")) == std::vector<uint8_t>({0xf9, 0x3c, 0x00}));
//
CHECK(json::parse("1.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x3c, 0x00})));
CHECK
(
json
::
parse
(
"1.0"
)
==
json
::
from_cbor
(
std
::
vector
<
uint8_t
>
({
0xf9
,
0x3c
,
0x00
})));
CHECK
(
json
::
to_cbor
(
json
::
parse
(
"1.1"
))
==
std
::
vector
<
uint8_t
>
({
0xfb
,
0x3f
,
0xf1
,
0x99
,
0x99
,
0x99
,
0x99
,
0x99
,
0x9a
}));
CHECK
(
json
::
parse
(
"1.1"
)
==
json
::
from_cbor
(
std
::
vector
<
uint8_t
>
({
0xfb
,
0x3f
,
0xf1
,
0x99
,
0x99
,
0x99
,
0x99
,
0x99
,
0x9a
})));
// half-precision float
//CHECK(json::to_cbor(json::parse("1.5")) == std::vector<uint8_t>({0xf9, 0x3e, 0x00}));
//
CHECK(json::parse("1.5") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x3e, 0x00})));
CHECK
(
json
::
parse
(
"1.5"
)
==
json
::
from_cbor
(
std
::
vector
<
uint8_t
>
({
0xf9
,
0x3e
,
0x00
})));
// half-precision float
//CHECK(json::to_cbor(json::parse("65504.0")) == std::vector<uint8_t>({0xf9, 0x7b, 0xff}));
//
CHECK(json::parse("65504.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x7b, 0xff})));
CHECK
(
json
::
parse
(
"65504.0"
)
==
json
::
from_cbor
(
std
::
vector
<
uint8_t
>
({
0xf9
,
0x7b
,
0xff
})));
//CHECK(json::to_cbor(json::parse("100000.0")) == std::vector<uint8_t>({0xfa, 0x47, 0xc3, 0x50, 0x00}));
CHECK
(
json
::
parse
(
"100000.0"
)
==
json
::
from_cbor
(
std
::
vector
<
uint8_t
>
({
0xfa
,
0x47
,
0xc3
,
0x50
,
0x00
})));
...
...
@@ -1134,15 +1134,15 @@ TEST_CASE("examples from RFC 7049 Appendix A")
// half-precision float
//CHECK(json::to_cbor(json::parse("5.960464477539063e-8")) == std::vector<uint8_t>({0xf9, 0x00, 0x01}));
//
CHECK(json::parse("-4.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0xc4, 0x00})));
CHECK
(
json
::
parse
(
"-4.0"
)
==
json
::
from_cbor
(
std
::
vector
<
uint8_t
>
({
0xf9
,
0xc4
,
0x00
})));
// half-precision float
//CHECK(json::to_cbor(json::parse("0.00006103515625")) == std::vector<uint8_t>({0xf9, 0x04, 0x00}));
//
CHECK(json::parse("-4.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0xc4, 0x00})));
CHECK
(
json
::
parse
(
"-4.0"
)
==
json
::
from_cbor
(
std
::
vector
<
uint8_t
>
({
0xf9
,
0xc4
,
0x00
})));
// half-precision float
//CHECK(json::to_cbor(json::parse("-4.0")) == std::vector<uint8_t>({0xf9, 0xc4, 0x00}));
//
CHECK(json::parse("-4.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0xc4, 0x00})));
CHECK
(
json
::
parse
(
"-4.0"
)
==
json
::
from_cbor
(
std
::
vector
<
uint8_t
>
({
0xf9
,
0xc4
,
0x00
})));
CHECK
(
json
::
to_cbor
(
json
::
parse
(
"-4.1"
))
==
std
::
vector
<
uint8_t
>
({
0xfb
,
0xc0
,
0x10
,
0x66
,
0x66
,
0x66
,
0x66
,
0x66
,
0x66
}));
CHECK
(
json
::
parse
(
"-4.1"
)
==
json
::
from_cbor
(
std
::
vector
<
uint8_t
>
({
0xfb
,
0xc0
,
0x10
,
0x66
,
0x66
,
0x66
,
0x66
,
0x66
,
0x66
})));
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录