- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我用 C 编写了一个简单的代码,但是当我将它移植到 mspgcc 时,它没有给我正确的值。这是我的代码的一部分:
unsigned short int xk=3588, yk=47541, yk1, sig=10, de=1;
unsigned long int xk1;
xk1=( xk+(sig*(yk-xk)*de));
yk1=xk1 % 65535;
我期望的结果是 xk1=443118
和 yk1=49908
,但在 mspgcc 中它给了我 xk1=yk1=49902
。不知道是选型的问题出在哪里?
编辑
这是我的完整代码
#include <stdio.h>
#include "uart1.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
int putchar(int c)
{
return uart1_putchar(c);
}
int main(void)
{
//variables
unsigned short int xk=3588, yk=47541, yk1, sig=10, de=1;
unsigned long xk1;
uart1_init();
xk1=( xk+(sig*((unsigned long)yk-xk)*de));
yk1=xk1 % 65536;
printf("xk1=%6lx\t\n,",xk1);
printf("yk1=%u\t\n,",yk1);
}
最佳答案
这个编译器的整数大小必须是 16 位,这是一个完全合法的系统。
你期望 xk1
为 443118。443118 % 65536 为 49902。
自计算:
unsigned short int xk=3588, yk=47541, yk1, sig=10, de=1;
unsigned long int xk1;
xk1=( xk+(sig*(yk-xk)*de));
只涉及unsigned short
值,这些被提升为 unsigned int
, 然后将结果计算为 unsigned int
, 最后将该值分配给 unsigned long
.但是多余的位早已丢失...计算是在 16 位无符号算术中完成的。
在装有 GCC 4.1.2 的 64 位 RHEL5 (AMD x86/64) 机器上进行。为了模拟 16 位整数计算,我在表达式中自由添加了(第二个副本)((unsigned short)(...))
。类型转换。双倍乘法只得到一个 Actor ;无论两次乘法的顺序如何,结果都不会改变(因为其中一个被乘数是 1,所以结果不会改变)。我已经包含了(的第三个副本)带有 (unsigned long)
的表达式 Actor 。
测试程序:
#include <stdio.h>
int main(void)
{
unsigned short int xk=3588, yk=47541, sig=10, de=1;
unsigned long int xk1;
xk1 = (xk+(sig*(yk-xk)*de));
printf("No Cast: %6lu = (%u+(%u*(%u-%u)*%u))\n", xk1, xk, sig, yk, xk, de);
xk1 = ((unsigned short)(xk+((unsigned short)(sig*((unsigned short)(yk-xk))*de))));
printf("US Cast: %6lu = (%u+(%u*(%u-%u)*%u))\n", xk1, xk, sig, yk, xk, de);
xk1 = (xk+(sig*((unsigned long)yk-xk)*de));
printf("UL Cast: %6lu = (%u+(%u*(%u-%u)*%u))\n", xk1, xk, sig, yk, xk, de);
return 0;
}
输出是:
$ gcc -Wall -Wextra -g -O3 -std=c99 xx.c -o xx && ./xx
No Cast: 443118 = (3588+(10*(47541-3588)*1))
US Cast: 49902 = (3588+(10*(47541-3588)*1))
UL Cast: 443118 = (3588+(10*(47541-3588)*1))
$
我认为第二个几乎不可读的表达式准确反射(reflect)(或足够准确地反射(reflect))16 位编译器计算表达式的方式 - 并且与您所看到的一致。
(47541-3588) 的结果是 43953。(10 * 43953) % 65536 的结果是 46314。加上 3588,结果应该是 49902。
我还添加了一个 (unsigned long)
转换为 yk
并运行表达式。也许是为了完全保真地使用 32 位 unsigned long
的机器, 我应该用 unsigned int
,但结果不会改变。我不知道您从哪里获得替代值(value) - 我需要查看您的完整工作程序(类似于我的)才能对此有任何想法。看起来好像您的某些计算部分“变为负数”,留下较大的(正)无符号值,但没有明显的理由让计算变为负数。
从评论中提取代码:
#include <stdio.h>
// -unused- #include "uart1.h"
// -unused- #include <stdlib.h>
// -unused- #include <stdint.h>
// -unused- #include <string.h>
// -unused- #include <math.h>
// -unused- int putchar(int c) { return uart1_putchar(c); }
int main(void)
{
//variables
unsigned short int xk=3588, yk=47541, yk1, sig=10, de=1;
unsigned long xk1;
// -not-needed-in-demo uart1_init();
xk1=( xk+(sig*((unsigned long)yk-xk)*de));
yk1=xk1 % 65535;
//printf("xk1=%6lx\t\n,",xk1);
//printf("yk1=%u\t\n,",yk1);
printf("xk1 = %6lx = %6u\n", xk1, xk1);
printf("yk1 = %6x = %6u\n", yk1, yk1);
}
65535 应该是 65536。行尾的制表符是不必要的,下一行开头的逗号也是不必要的(但这些都是纯粹的装饰品)。
更严重(但对手头的问题无关紧要,因为它未被使用),<stdio.h>
定义一个名为 putchar()
的函数(通常也是一个宏) .您可能不应该定义自己的函数 putchar
, 但如果你必须这样做,你通常应该从 <stdio.h>
取消定义宏(假设有一个)。 .我承认代码在我的机器上编译正常——没有链接,但这是预料之中的;也许有一天,我会追踪到什么putchar()
真的在这台机器上。
显示的代码产生了正确/预期的答案。
我能看到产生观察到的不正确行为的唯一方法是删除多余的代码:
#include <stdio.h>
int main(void)
{
unsigned short int xk=3588, yk=47541, yk1, sig=10, de=1;
unsigned long xk1;
xk1=( xk+(sig*((unsigned long)yk-xk)*de));
yk1=xk1 % 65536;
printf("xk1= %6lx = %6lu\n", xk1, xk1);
printf("yk1= %6x = %6u\n", yk1, yk1);
xk1=( xk+(sig*((short)yk-xk)*de));
yk1=xk1 % 65536;
printf("xk1= %6lx = %6lu\n", xk1, xk1);
printf("yk1= %6x = %6u\n", yk1, yk1);
}
在我的 64 位机器(目前是 MacOS X 10.6.7 和 GCC 4.6.0)上运行时,我得到:
xk1= 6c2ee = 443118
yk1= c2ee = 49902
xk1= fffffffffffcc2ee = 18446744073709339374
yk1= c2ee = 49902
忽略十六进制值中的 8 个额外 F,我得到 0xFFFCC2EE 而不是您得到的 0xFFFBC2EE。我无法解释这种差异。但是您可以看到,如果中间结果是一个带符号的 16 位数量,您最终会得到与您看到的结果差不多的结果。
那么问题来了:为什么里面会有signed操作呢?我没有很好的解释。我认为您可能需要查看汇编代码并弄清楚发生了什么;您甚至可能会发现编译器中的错误。
关于c - mspgcc 中的意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5948973/
我用 C 编写了一个简单的代码,但是当我将它移植到 mspgcc 时,它没有给我正确的值。这是我的代码的一部分: unsigned short int xk=3588, yk=47541, yk1,
我正在编写几个我想内联的函数。 阅读 here并在所有声明和定义上使用带有内联的第二个 c99 内联选项,如下所示: extern inline void SPFD54124B_write_cmd(u
所以,我正在尝试编译代码,用 C 语言为 linux SO 中的 msp430fx 编写。我最近重新编译新版本的 mspgcc,因为之前使用的是 4.3,它与扩展模式(20 位 -mlarge)不兼容
如何使用 mspgcc 在 C 中启用和禁用(清除并设置 GIE SR 位)? 最佳答案 /*interrupt.c ganeshredcobra@gmail.com GPL */ #include
我是一名优秀的程序员,十分优秀!