This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] 无符号 int degision

Guru**** 2568565 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1173802/signed-to-unsigned-int-devision

您好!
客户单步执行有符号/无符号 int degision、这会烧毁他的电源。 您能否检查以下编译器行为是否正确或有错误? 编译期间没有编译器警告。

CAL_mg/s16TestRes1  = CAL_mg/s16TestNom / 4U 的结果为16379、不正确。

正除法的正确行为:

Compiler: ti-cgt-c2000_18.12.8.LTS

#--- Compiler settings --------------------------------------------------------
compiler_flags =  \
                  --silicon_version=28                         \
                  --unified_memory                             \
                  --opt_level=3                                \
                  --opt_for_speed=4                            \
                  --opt_for_space                              \
                  --c99                                        \
                  --single_inline                              \
                  --cla_support=cla2                           \
                  --float_support=fpu32                        \
                  --tmu_support=tmu0                           \
                  --vcu_support=vcu0                           \
                  --fp_mode=relaxed                            \
                  $(subst -I,--include_path=,$(includes))      \
                  --symdebug:dwarf                             \
                  --define=CPU1                                \
                  --define=_FLASH                              \
                  --quiet                                      \
                  --verbose_diagnostics                        \
                  --diag_warning=225                           \
                  --diag_suppress=10063                        \
                  --issue_remarks                              \
                  --preproc_with_compile                       \
                  --gen_data_subsections=off                   \
                  --advice:performance=all                     \
                  --pp_directory="$(pp_path)"                  \
                  --obj_directory="$(obj_path)"                \
                  --temp_directory="$(tmp_path)"               \
                  --asm_directory="$(asm_path)"                \
                  --list_directory="$(lst_path)"

static int16   CAL_mg_s16TestRes1;
static int16   CAL_mg_s16TestRes2;
static int16   CAL_mg_s16TestRes3;
static int16   CAL_mg_s16TestRes4;
static int16   CAL_mg_s16TestNom;
static int16   CAL_mg_s16TestDenom;
static Uint16  CAL_mg_u16TestDenom;


     /* TEST TEST */
     CAL_mg_s16TestRes1    = 0;
     CAL_mg_s16TestRes2    = 0;
     CAL_mg_s16TestRes3    = 0;
     CAL_mg_s16TestNom     = 20;
     CAL_mg_s16TestDenom   = 4;
     CAL_mg_u16TestDenom   = 4u;

     CAL_mg_s16TestRes1  = CAL_mg_s16TestNom / 4u;
     CAL_mg_s16TestRes2  = CAL_mg_s16TestNom / 4;
     CAL_mg_s16TestRes3  = CAL_mg_s16TestNom / CAL_mg_s16TestDenom;
     CAL_mg_s16TestRes4  = CAL_mg_s16TestNom / CAL_mg_u16TestDenom;

不正确的否定行为除法:

     /* TEST TEST */
     CAL_mg_s16TestRes1    = 0;
     CAL_mg_s16TestRes2    = 0;
     CAL_mg_s16TestRes3    = 0;
     CAL_mg_s16TestNom     = -20;
     CAL_mg_s16TestDenom   = 4;
     CAL_mg_u16TestDenom   = 4u;

     CAL_mg_s16TestRes1  = CAL_mg_s16TestNom / 4u;
     CAL_mg_s16TestRes2  = CAL_mg_s16TestNom / 4;
     CAL_mg_s16TestRes3  = CAL_mg_s16TestNom / CAL_mg_s16TestDenom;
     CAL_mg_s16TestRes4  = CAL_mg_s16TestNom / CAL_mg_u16TestDenom;

此致、Holger

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    它用于什么器件?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、Nima、
    它是 F280049。 编译器版本:TI-CGT-C2000_18.12.8.LTS

    此致、Holger

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    几个问题:

    您附加了什么 Pinmux 映像? 该图像与故障之间是否存在相关性。

    2.您是否有我们可以在 launchpad 上测试的压缩项目文件?

    3.单步执行指令是如何烧断电源的?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、Nima、

    1.很抱歉我发布了错误的图片。 现已更正。

    2.不需要.zip 项目。 您可以轻松地在上面的线程中测试 c 代码。

    3.这只是显示故障的测试代码,在应用程序中,这些值是在算法中计算的,很难找到故障

    此致、Holger

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    好的、谢谢。 这是感恩节假期、因此响应可能会延迟、但我会将您连接到合适的 SW/编译器人员。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="8038" URL"~/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1173802/signed-to-unsigned-int-devision "]检查以下编译器行为是否正确或存在错误

    没错。

    表达式...

    int16_variable / 4U

    (笑声) 首先将所有操作数转换为公共类型来计算。  在本例中、该常用类型是无符号16位整数。  然后执行无符号16位除法。  由于这是无符号4除法、因此它更改为无符号2向右移位。  因此,它与您编写的内容相同...

    (uint16_t) int16_variable >> 2.

    在本例中、int16_variable 包含值-20。  当更改为16位无符号时、它是0xffffff.  0x3ffb。  以十进制表示、即16379。

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、George、

    客户使用 GCC 编译器进行了检查、该编译器的行为与我们的不同:

    静态 int16_t  CAL_mg/s16TestRes1;
    静态 int16_t  CAL_mg/s16TestRes2;
    静态 int16_t  CAL_mg/s16TestRes3;
    静态 int16_t  CAL_mg/s16TestRes4;
    静态 int16_t  CAL_mg/s16TestNom;
    静态 int16_t  CAL_mg/s16TestDenom;
    静态 uint16_t CAL_mg/u16TestDenom;

    /*测试测试*/
    CAL_mg/s16TestRes1   = 0;
    CAL_mg/s16TestRes2   = 0;
    CAL_mg/s16TestRes3   = 0;
    CAL_mg/s16TestNom    =-20;
    CAL_mg/s16TestDenom  = 4;
    CAL_mg/u16TestDenom  = 4U;

    CAL_MG_s16TestRes1 = CAL_MG_s16TestNom / 4U;
    CAL_MG_s16TestRes2 = CAL_MG_s16Test标称/ 4;
    CAL_MG_s16TestRes3 = CAL_MG_s16TestNom / CAL_MG_s16TestDenom;
    CAL_MG_s16TestRes4 = CAL_MG_s16TestNom / CAL_MG_u16TestDenom;

    printf ("CAL_mg/s16TestRes1 =%i \n"、CAL_mg/s16TestRes1);
    printf ("CAL_mg/s16TestRes2 =%i \n"、CAL_mg/s16TestRes2);
    printf ("CAL_mg/s16TestRes3 =%i \n"、CAL_mg/s16TestRes3);
    printf ("CAL_mg/s16TestRes4 =%i \n"、CAL_mg/s16TestRes4);

    此致、Holger

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="8038" URL"~/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1173802/signed-to-unsigned-int-devision/4451894 #4451894"]客户使用行为不同的 GCC 编译器进行了检查[/quot]

    是的、确实如此。  因为在主机 GCC 系统上、类型 int 为32位。  在 C2000上、int 为16位。

    考虑我在上一篇文章中所写的描述。

    [引用 userid="4373 " URL"~/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1173802/signed-to-unsigned-int-devision/4426813 #4426813"]

    表达式...

    int16_variable / 4U

    (笑声) 首先将所有操作数转换为公共类型来计算。  在本例中、该常用类型是无符号16位整数。  然后执行无符号16位除法。  由于这是无符号4除法、因此它更改为无符号2向右移位。  因此,它与您编写的内容相同...

    (uint16_t) int16_variable >> 2.

    在本例中、int16_variable 包含值-20。  当更改为16位无符号时、它是0xffffff.  0x3ffb。  以十进制表示、即16379。

    [/报价]

    一般而言是正确的。  但是、在 int 为32位的系统上、一些细节有所不同。  这是它在这样一个系统上的工作方式。

    表达式...

    int16_variable / 4U

    (笑声) 首先将所有操作数转换为公共类型来计算。 在本例中、该常用类型是无符号32位整数。  然后执行无符号32位除法。  由于这是无符号4除法、因此它更改为无符号2向右移位。  因此,它与您编写的内容相同...

    (uint32_t) int16_variable >> 2.

    在本例中、int16_variable 包含值-20。  当更改为32位无符号数时、它是0xffffffec 值。  0x3ffffffec >> 2为0x3ffffffb。  以十进制表示、即  1073741819。

    printf 写入-5、而不是  1073741819 .为什么?  因为在输出 表达式之前、它首先被分配给 Int16_t 变量。  将其称为 Int16_Result。  发生这种情况时、仅保留低16位。  因此、为 Int16_Result 分配了0xFFb。  当 printf包含0xFFb 的16位宽带符号变量进行%i 转换时、它会将-5写入。   

    如果这是您在 C2000上所需的行为、一种方法是使用强制除法作为32位无符号执行。  例如...

    CAL_mg_s16TestRes1  = (int32_t) CAL_mg_s16TestNom / 4u;

    谢谢、此致、

    乔治