user-0 提问: 使用C函数库中的幂函数pow()遇到个问题

回复:
user: user-1
content: pow 函数 C 只有 double pow(double ,double ) 1个 另有 powf 用于float,powl 用于 long double C++有四个重载函数 long double pow(long double ,long double) double pow (double ,double) float pow (float,float) long double pow(long double ,int ) //或者 double pow(double ,int)   如果 pow(10,2) 调用 double pow(double,double) 结果是不精确的 如果 调用 pow(double ,int) 结果是精确的 另一种可能是，产生二义性，编译出错。

user: user-2
content: 因为math.h中的pow函数的两个形参是double类型的。如果传入pow(10, 2)则编译器会自动将这两个立即数转换为double类型，但是如果传入pow(10, n)，因为n被声明为整型，所以不会被转换为double类型，从而导致计算误差。在pow(10,n)中的n前面做强制类型转换或许可以解决这个问题，像这样：pow(10, (double)n)

user: user-3
content: 引用 10 楼 qq_35899178 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] int运算会发生溢出 赵老师，你的那个kg游戏是不是又坏了，win10打开不了啊[/quote] 在64位Windows下： 64位exe和dll在目录c:\windows\system32目录下； 32位exe和dll在目录c:\windows\syswow64目录下； 所以要注意：     在win64位系统下注册32位ocx或dll需要将32位ocx或dll拷贝到c:\windows\syswow64\目录下。     且注册要用c:\windows\syswow64\regsvr32 xxxxxxx.ocx或dll  kg游戏依赖32位的MCI32.OCX，所以如果要在64位的WIn10下顺利运行的话，需要 c:\windows\syswow64\regsvr32 MCI32.OCX

user: user-4
content: 强制转换int有可能导致数据被截断  浮点数计算是有误差的  如果pow(10,n)计算出的结果是99.99....  转换后就变成了99；如果计算结果是100.00....，转换后就是100

user: user-4
content: 强制转换int有可能导致数据被   引用 13 楼 yayouyayou 的回复:[quote=引用 11 楼 paschen 的回复:] 强制转换int有可能导致数据被截断  浮点数计算是有误差的  如果pow(10,n)计算出的结果是99.99....  转换后就变成了99；如果计算结果是100.00....，转换后就是100 是的，其实比较不明白的地方是为什么直接对这个函数进行强制类型转换是99，而先赋值给一个浮点变量，然后对浮点变量强制类型转换结果就是100。如果说pow(10,n)计算出来的结果是99.99...，那么赋值给一个浮点变量的时候存储的形式不是应该是一样的吗，因为pow（）本身就是返回的double型的变量啊。还有一点，就是（int）pow(10,2),然后赋值给一个int变量，结果输出确实100，这里用一个int型的变量n=2，与直接用常数2即使有区别，不是都会先转换为double变量然后再进行运算的吗，为什么结果会有区别，就是不太明白编译器到底是怎么处理的，表示不理解。[/quote]  那你得看pow的反汇编了

user: user-5
content: 不是说用gdb看看吗，编译器也可能有bug

user: user-0
content: 引用 11 楼 paschen 的回复:强制转换int有可能导致数据被截断  浮点数计算是有误差的  如果pow(10,n)计算出的结果是99.99....  转换后就变成了99；如果计算结果是100.00....，转换后就是100 是的，其实比较不明白的地方是为什么直接对这个函数进行强制类型转换是99，而先赋值给一个浮点变量，然后对浮点变量强制类型转换结果就是100。如果说pow(10,n)计算出来的结果是99.99...，那么赋值给一个浮点变量的时候存储的形式不是应该是一样的吗，因为pow（）本身就是返回的double型的变量啊。还有一点，就是（int）pow(10,2),然后赋值给一个int变量，结果输出确实100，这里用一个int型的变量n=2，与直接用常数2即使有区别，不是都会先转换为double变量然后再进行运算的吗，为什么结果会有区别，就是不太明白编译器到底是怎么处理的，表示不理解。

user: user-6
content: 引用 3 楼 zhao4zhong1 的回复:int运算会发生溢出 赵老师，你的那个kg游戏是不是又坏了，win10打开不了啊

user: user-0
content: 感谢老师赐教了！！！辛苦，辛苦！！！那这里应该是用的这个编译器对返回double类型的函数的转换与转换一个double变量的方式不同，100这个数可能在double实际是99.9999***，直接转换成int就成了99。而一个定义成double变量的数，编译器转换的方式不同，不会出现这种情况，不知道这样理解对不对？

user: user-3
content: //Round(1.234,2) = 1.23 //Round(1.234,0) = 1.0 //Round(123.4,-1) = 120.0 double Round(double dVal, short iPlaces) {     double dRetval;     double dMod = 0.0000001;     if (dVal<0.0) dMod=-0.0000001;     dRetval=dVal;     dRetval+=(5.0/pow(10.0,iPlaces+1.0));     dRetval*=pow(10.0,iPlaces);     dRetval=floor(dRetval+dMod);     dRetval/=pow(10.0,iPlaces);     return(dRetval); }  double round(double dVal, short iPlaces) //iPlaces>=0 {     unsigned char s[20];     double dRetval;      sprintf(s,"%.*lf",iPlaces,dVal);     sscanf(s,"%lf",&dRetval);     return (dRetval); }

user: user-3
content: 浮点数格式 http://bbs.csdn.net/topics/390676437

user: user-0
content: 可是这里的数最大的才200，int类型怎么会溢出呢？

user: user-5
content: 至少高版本gcc没有问题。你用gdb看看代码是怎么翻译的吧。我gcc 4.4和gcc 7.4都没有问题

user: user-7
content: vs下都是100 100

user: user-3
content: int运算会发生溢出

user: user-3
content: C++ Floating-Point Constants Floating-point constants specify values that must have a fractional part. These values contain decimal points (.) and can contain exponents.  Syntax  floating-constant :  fractional-constant exponent-partopt floating-suffixopt digit-sequence exponent-part floating-suffixopt  fractional-constant :  digit-sequenceopt . digit-sequence digit-sequence .  exponent-part :  e signopt digit-sequence E signopt digit-sequence  sign : one of  + –  digit-sequence :  digit digit-sequence digit  floating-suffix :one of  f l F L  Floating-point constants have a “mantissa,” which specifies the value of the number, an “exponent,” which specifies the magnitude of the number, and an optional suffix that specifies the constant’s type. The mantissa is specified as a sequence of digits followed by a period, followed by an optional sequence of digits representing the fractional part of the number. For example:  18.46 38.  The exponent, if present, specifies the magnitude of the number as a power of 10, as shown in the following example:  18.46e0      // 18.46 18.46e1      // 184.6  If an exponent is present, the trailing decimal point is unnecessary in whole numbers such as 18E0.  Floating-point constants default to type double. By using the suffixes f or l (or F or L — the suffix is not case sensitive), the constant can be specified as float or long double, respectively.  Although long double and double have the same representation, they are not the same type. For example, you can have overloaded functions like  void func( double );  and   void func( long double );

user: user-3
content: 常量也有类型！ C++ Integer Constants Integer constants are constant data elements that have no fractional parts or exponents. They always begin with a digit. You can specify integer constants in decimal, octal, or hexadecimal form. They can specify signed or unsigned types and long or short types.  Syntax  integer-constant :  decimal-constant integer-suffixopt octal-constant integer-suffixopt hexadecimal-constant integer-suffixopt 'c-char-sequence'  decimal-constant :  nonzero-digit decimal-constant digit  octal-constant :  0 octal-constant octal-digit  hexadecimal-constant :  0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-constant hexadecimal-digit  nonzero-digit : one of  1 2 3 4 5 6 7 8 9  octal-digit : one of  0 1 2 3 4 5 6 7  hexadecimal-digit : one of  0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F  integer-suffix :  unsigned-suffix long-suffixopt long-suffix unsigned-suffixopt  unsigned-suffix : one of  u U  long-suffix : one of  l L  64-bit integer-suffix :  i64  To specify integer constants using octal or hexadecimal notation, use a prefix that denotes the base. To specify an integer constant of a given integral type, use a suffix that denotes the type.  To specify a decimal constant, begin the specification with a nonzero digit. For example:  int i = 157;   // Decimal constant int j = 0198;  // Not a decimal number; erroneous octal constant int k = 0365;  // Leading zero specifies octal constant, not decimal  To specify an octal constant, begin the specification with 0, followed by a sequence of digits in the range 0 through 7. The digits 8 and 9 are errors in specifying an octal constant. For example:  int i = 0377;   // Octal constant int j = 0397;   // Error: 9 is not an octal digit  To specify a hexadecimal constant, begin the specification with 0x or 0X (the case of the “x” does not matter), followed by a sequence of digits in the range 0 through 9 and a (or A) through f (or F). Hexadecimal digits a (or A) through f (or F) represent values in the range 10 through 15. For example:  int i = 0x3fff;   // Hexadecimal constant int j = 0X3FFF;   // Equal to i  To specify an unsigned type, use either the u or U suffix. To specify a long type, use either the l or L suffix. For example:  unsigned uVal = 328u;             // Unsigned value long lVal = 0x7FFFFFL;            // Long value specified                                    //  as hex constant unsigned long ulVal = 0776745ul;  // Unsigned long value