【问题标题】:Represent decimal numbers using integers使用整数表示十进制数
【发布时间】:2019-03-21 13:10:54
【问题描述】:

我正在尝试想出一种方法来使用软件解决我的硬件限制。我遇到的问题是我只能将整数(整数)写入我的硬件,但我希望在计算结果等时使用十进制数。

这里想到了带有转换因子的 HexaDecimals。我可以在技术上发送一个像 (00)1105 这样的十六进制值,然后将其解释为 11.05 (E^-2) 软件端.

这意味着我在技术上可以在软件端处理十进制数字,而只将整数发送到我的硬件。

有没有更好的方法来处理这个问题? (二进制值不是一个选项,因为可以发送的消息有长度限制。(长度 。我不会超过 E^5 (nnnnn)预期用途。)

当前的这种方法存在明显的问题,所有方法都可能存在问题但是我很好奇还有哪些其他方法可以实现?

不用担心硬件,只要把它当作一个黑盒子,整数是唯一有效的输入。

【问题讨论】:

  • 如果没有必要,我会放弃使用一些浮点实现。硬件可以处理的整数范围是多少?你需要表示的十进制数的范围是多少?
  • 硬件可能是一个“黑匣子”,但可能你想向它发送值,以便执行一些操作并产生结果。此类信息对于决定哪种方法是“最佳”至关重要,但您没有提供此类信息。
  • 您为什么认为将十六进制值解释为十进制值是一种好方法?十六进制只是一种字符串表示,因此这种隐式转换为十进制似乎非常随意。为什么不使用十进制值并在某处设置一个固定点(即 100 是 1.00)
  • 消息中究竟可以发送什么? (最多)10 个字节的任何值?一串(最多)10个十六进制数字?还有什么?...
  • @Joel 你的问题不清楚,你没有回答所有的评论......

标签: c math


【解决方案1】:

根据我从问题中可以理解的情况,固定点可能会对您有所帮助。 定点允许您对整数进行十进制运算,假设小数点后的位数是预先知道的。

这是固定点的快速而肮脏的实现:

#include <stdio.h>

#define FP_ABS(x) ((x) >= 0 ? (x) : -(x))

// This will determine the number of digits after the decimal point.
// It must be a power of 10.
// In this case, you can represent all the numbers in the range -2147483.648 to 2147483.647
// or if you want to be safe -2000000.000 to 2000000.000
#define FP_DECIMAL_FACTOR 1000

#define FP_LIT(x) ((int)((x) * FP_DECIMAL_FACTOR))
#define FP_ADD(x, y) ((x) + (y))
#define FP_SUB(x, y) ((x) - (y))
#define FP_MUL(x, y) ((x) * (y) / FP_DECIMAL_FACTOR)
#define FP_DIV(x, y) ((x) * FP_DECIMAL_FACTOR / (y))

#define FP_INT_PART(x) ((x) / FP_DECIMAL_FACTOR)
#define FP_DEC_PART(x) (FP_ABS((x) % FP_DECIMAL_FACTOR))


int main()
{
    int a = FP_LIT(25.01);
    int b = FP_LIT(12.2);

    printf("a = %d.%03d\n", FP_INT_PART(a), FP_DEC_PART(a));
    printf("b = %d.%03d\n", FP_INT_PART(b), FP_DEC_PART(b));

    int a_plus_b = FP_ADD(a, b);
    printf("a + b = %d.%03d\n", FP_INT_PART(a_plus_b), FP_DEC_PART(a_plus_b));

    int a_minus_b = FP_SUB(a, b);
    printf("a - b = %d.%03d\n", FP_INT_PART(a_minus_b), FP_DEC_PART(a_minus_b));

    int b_minus_a = FP_SUB(b, a);
    printf("b - a = %d.%03d\n", FP_INT_PART(b_minus_a), FP_DEC_PART(b_minus_a));

    int a_multiply_b = FP_MUL(a, b);
    printf("a * b = %d.%03d\n", FP_INT_PART(a_multiply_b), FP_DEC_PART(a_multiply_b));

    int a_divide_b = FP_DIV(a, b);
    printf("a / b = %d.%03d\n", FP_INT_PART(a_divide_b), FP_DEC_PART(a_divide_b));

    int b_divide_a = FP_DIV(b, a);
    printf("b / a = %d.%03d\n", FP_INT_PART(b_divide_a), FP_DEC_PART(b_divide_a));

    return 0;
}

【讨论】:

  • 好建议。注意FP_MULFP_DIV 应该使用long long 算术来减少算术溢出产生错误结果的可能性。
【解决方案2】:

你根本不清楚,如果你只需要在没有 FPU 的情况下进行浮点计算,只需使用像 Floating-point Library for Integer Processors 这样的库

【讨论】:

    【解决方案3】:

    我记得我在考试中做过类似的事情。我认为这取决于应用程序。

    对于数值处理,您可以执行以下操作:

    • 通过减去平均值并除以模块的最大值来缩放 [-1;1] 范围内的所有数字。这样,乘法将属于同一范围
    • 将所有数字乘以 2 的幂,具体取决于您的架构(例如 2^322^64
    • 将值四舍五入为整数
    • 做你的操作
    • 通过除以 2 的幂来重新调整值
    • 将数字恢复到原始范围内

    我会尽快给你更多细节。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-29
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      • 2015-04-01
      • 2021-09-29
      相关资源
      最近更新 更多