带负数的嵌入式除法

标签 embedded division negative-number

在我多年的嵌入式编程生涯中,我通常不需要使用负数。这很疯狂,但它们在我的工作中并不经常出现。

我目前正在处理一个传感器读数,该读数可以是正值,也可以是负值,需要按 0.006 缩放,保留符号。为了避免在运行时进行不必要的浮点计算,我有一个算法将其转换为分子和分母 (3/500)。对于正数,一切都按预期进行,但对于负数,情况如下:

Raw data:         -103
Multiplied by 3:  -309
Divided by 500:   36893488147419102

我弄清楚了这个数字的来源,并且我有一个解决方法,但我宁愿相信数学就是数学。

这是相同的十六进制计算:

Raw data:         0xFFFFFFFFFFFFFF99
Multiplied by 3:  0xFFFFFFFFFFFFFECB
Divided by 500:   0x0083126E978D4FDE

在计算器 (SpeedCrunch) 中:

0xFFFFFFFFFFFFFECB/500 = 0x83126E978D4FDE.9D2F1A9FBE76C8B44

原始 36893488147419102 是 SpeedCrunch 结果的组成部分 0x83126E978D4FDE

我不想保存符号,进行正除法,然后每次用负数除法时都重新添加符号。这是怎么回事?

环境是CortexM3 micro,使用c++11的GCC4.9.3。计算在 int64_t 上完成,分子/分母为 uint64_t

编辑: 以下是响应 Michael 评论的代码片段:

int64_t data = -103;
uint64_t resolutionNumerator = 3;
uint64_t resolutionDenominator = 500;

data *= resolutionNumerator;
data /= resolutionDenominator;

最佳答案

使用相同宽度的有符号和无符号整数(例如 uint64_tint64_t)进行运算,会导致有符号操作数转换为无符号操作数的类型。

因此这两个表达式是等价的:

  • (int64_t) -103 * (uint64_t) 3/(uint64_t) 500
  • (uint64_t) -103 * (uint64_t) 3/(uint64_t) 500

如果分子和分母使用有符号类型 int64_t,则结果将保留符号。

关于带负数的嵌入式除法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34231301/

相关文章:

percentage - 如何在 RPGLE 中声明小数位固定或自由格式?

javascript - 如何在 JavaScript 中计算负整数的模数?

c# - 数组中的正整数总和为负数

delphi - 是否有 Delphi EncodeDate/DecodeDate 函数版本可以处理 B.C.日期?

c - make 运行时出错。冲突的类型和先前的声明

c - 使用指针功能 - 1 台设备上的 2 个独立应用程序

c - 在 C 中有什么函数可以代替 sprintf() 吗?编译后代码量太大

c - C中的整数除法与无符号短

java - 为什么当我尝试在 try block 内进行类型转换时,我的 java 代码会失败?

embedded - 工作站和嵌入式程序员的心态差异