c++ - C ++中相互转换不同签名类型的最佳方法?
问题描述
通信对等方发送了一个 uint64_t 数据字段,它带有我需要存储到不支持无符号整数类型的 Postgresql-11 数据库中的订单 ID。虽然实际数据可能超过 2^63,但我认为INT8
Postgresql11 中的一个文件可以容纳它,如果我仔细进行一些转换。
假设有:
uint64_t order_id = 123; // received
int64_t to_db; // to be writed into db
我计划使用以下方法之一将 uint64_t 值转换为 int64_t 值:
to_db = order_id;
// 直接赋值;to_db = (int64_t)order_id;
//c 风格的强制转换;to_db = static_cast<int64_t>(order_id);
to_db = *reinterpret_cast<const int64_t*>( &order_id );
当我需要从数据库加载它时,我可以进行反向转换。
我知道它们都可以工作,我只是对哪个最符合 C++ 标准感兴趣。
换句话说,哪种方法在任何编译器的任何 64 位平台上始终有效?
谢谢!!!
解决方案
取决于它将在哪里编译和运行......没有 C++20 支持的任何不能完全移植的。
没有那个的最安全的方法是通过改变值的范围来自己进行转换,比如
int64_t to_db = (order_id > (uint64_t)LLONG_MAX)
? int64_t(order_id - (uint64_t)LLONG_MAX - 1)
: int64_t(order_id ) - LLONG_MIN;
uint64_t from_db = (to_db < 0)
? to_db + LLONG_MIN
: uint64_t(to_db) + (uint64_t)LLONG_MAX + 1;
如果order_id
大于 (2^63 -1),则order_id - (uint64_t)LLONG_MAX - 1
产生非负值。如果不是,则强制转换为有符号是明确定义的,并且减法可确保将值转移到负范围内。
在反向转换期间,to_db + LLONG_MIN
将值放入 [0, ULLONG_MAX] 范围内。
并在阅读时做相反的事情。您使用的数据库平台或编译器在将无符号值的二进制表示转换为有符号时可能会做一些糟糕的事情,更不用说确实存在不同的有符号格式。
出于同样的原因,跨平台协议通常涉及使用字符串格式或“最小位值”来将浮点值表示为整数,即编码定点。
推荐阅读
- javascript - 转换为字符串 NodeJS Express http 响应在 AngularJS 中返回
- wordpress - WordPress中的电子邮件发送问题
- laravel - 如何在laravel中显示存储为数组的多个图像?
- python - 加快numpy数组分配
- spring - @Cacheable 注解给出 404
- php - 如何从php中的url获取id值
- asp.net - 捕获所有查询参数、模型数据、路由到动作方法以防止 XSS 攻击
- python - 在 DRF+Angular 中下载文件的问题
- mysql - 在 Laravel 中使用 foreach 加入查询
- mobile - 移动浏览器 Aframe-AR.js 无法识别点击事件