2012-10-20 56 views
1

我想在嵌入式C/C++环境中做一些简单的变量操作。出于某种原因,我总是因此而得到零。C长无符号整数操作

下面是代码

void Heater::setPower(int newpower) 
{ 
    printf("1 new power %d\n",newpower); 

    if(newpower != power) 
     power = newpower; 
    else 
     return; 

    printf("2 new power %d\n",power); 

    // Set Duty 
    long unsigned int newduty = 0; 

    // Protect from divide by zero 
    if(power <= 0) 
    { 
     printf("2.5 zeroed\n"); 
     newduty = 0; 
     power = 0; 
    } 
    else 
     newduty = period*(power/100); 

    printf("3 setduty %lu period %lu\n", newduty, period); 

    setDuty(newduty); 
} 

这里是输出我收到

1 new power 76 
2 new power 76 
3 setduty 0 period 10000000 

所以我知道该号码是76.我知道是使得它过去的第一道关卡,和第二。但不知何故,在简单的数学方程中它变成了零。 “句号”也是一个长整型无符号整数,并且在类def中声明,但是您可以看到输出是合适的。

为什么这一直下降到零?什么不见​​了?我是否需要为更大的数字包含一些特殊的内容,或者我可以不使用简单的运算符*和/或在长整型无符号整数或什么东西上?

我正在处理高数字(x < = 10,000,000),因为我正在使用内核级别pwm。

回答

6

您遇到的问题是,power是一个整数,所以当你/100你实际使用的0结果结束了由于integer division规则。这意味着当您乘以period时,整个结果为0

根据您的精度要求,可能足以使使power了一倍,但是要知道,(power/100)*period通常会产生一个小数结果等存储可能还需要结果的两倍。

如果你必须坚持整数只是做((power*period)/100)这将给你一个合理的准确结果,因为power*period成为一个很大的数字之前,该部门使任何0。使用整数除法,在括号中可以是获得07600000(在你的情况下)之间的差异。

+0

我曾经有过这样的“newduty =(long unsigned int)period *(power/100);”认为它可以解决类型转换问题。我不想将它存储为double,我需要它是非浮点数,因为我将它写入到接收整数的/ sys/class/pwm。 “newduty =(long unsigned int)period *(power/100.0f);”修复它可能吗? – napierzaza

+0

好吧,把100改成100.0f,然后输入回到long unsigned int,效果很好。谢谢! – napierzaza

+0

@napierzaza这不是一个铸造问题,它是一个整数除法问题。因为(76/100)<1',它会在你的equasion上放一个'0'。如果你不得不坚持整数,那么'(power * period)/ 100)'这会给你一个相当准确的结果,因为'power * period'在分割之前变成一个很大的数字。 – Benj

0

make newduty and power as double。因为它的整数类型给出0

+1

除非功率也是双倍,否则这将不起作用。 – Benj

+0

@Benj:对,更新 –