C 将一个小的正双精度浮点数除以一个大的正数,得到的结果是负数

C 将一个小的正双精度浮点数除以一个大的正数,得到的结果是负数,c,math,double,C,Math,Double,我正在用C写一个代码,它分析所有排序技术的时间复杂度的常数因子。我正在对这些常数进行统计研究。要做到这一点,我必须找到两个正双数的比率。令人惊讶的是,我得到了一个否定的结果。有人能帮我理解我在这里遗漏了什么吗 我开始在维基上挖掘这个,但这似乎并没有我想要的答案 #include <stdio.h> int main(void) { // your code goes here int i=1500; double j=9265.49; double

我正在用C写一个代码,它分析所有排序技术的时间复杂度的常数因子。我正在对这些常数进行统计研究。要做到这一点,我必须找到两个正双数的比率。令人惊讶的是,我得到了一个否定的结果。有人能帮我理解我在这里遗漏了什么吗

我开始在维基上挖掘这个,但这似乎并没有我想要的答案

#include <stdio.h>

int main(void) {
    // your code goes here
    int i=1500;
    double j=9265.49;
    double result=(double)j/((double)(i*i*i*i));
    printf("%lf",result);
    return 0;
}
#包括
内部主(空){
//你的密码在这里
int i=1500;
双j=9265.49;
双重结果=(双重)j/(双重)(i*i*i*i));
printf(“%lf”,结果);
返回0;
}

结果是-0.000007,这显然是错误的

整数溢出

i*i*i*i
int
math和
int
overflow1,它是未定义的行为(UB)

在OP的例子中,
i*i*i
-->变成了
-1266441984
左右


避免乘法运算中的溢出。用更广泛的数学知识进行乘法运算

int main(void) {
  int i = 1500;
  double j = 9265.49;
  // double result=(double)j/((double)(i*i*i*i));
  double result = (double) j / ((double) i * i * i * i);
  printf("%e", result);
  return 0;
}
输出

1.830220e-09

有关代码的更多详细信息,请参见
i*i*i



1当
INT\u MAX<5062500000000
与32位
INT
INT溢出时

i*i*i*i
int
math和
int
overflow1,它是未定义的行为(UB)

在OP的例子中,
i*i*i
-->变成了
-1266441984
左右


避免乘法运算中的溢出。用更广泛的数学知识进行乘法运算

int main(void) {
  int i = 1500;
  double j = 9265.49;
  // double result=(double)j/((double)(i*i*i*i));
  double result = (double) j / ((double) i * i * i * i);
  printf("%e", result);
  return 0;
}
输出

1.830220e-09

有关代码的更多详细信息,请参见
i*i*i


1当
INT\u MAX<506250000000
与32位
INT
整数溢出相同时:

#包括
#包括
#包括
int main(int argc,char*argv[]){
int i=1500;
int32_t i32=1500;
uint32_t u32=1500;
printf(“i:%lf\n”,(双精度)(i*i*i*i));
printf(“i32:%lf\n”(双精度)(i32*i32*i32*i32*i32));
printf(“u32:%lf\n”(双精度)(u32*u32*u32*u32*u32));
长整数li=1500;
int64_t i64=1500;
uint64_t u64=1500;
printf(“li:%lf\n”,双精度)(li*li*li*li));
printf(“i64:%lf\n”,(双精度)(i64*i64*i64*i64*i64));
printf(“u64:%lf\n”,(双精度)(u64*u64*u64*u64*u64));
返回(0);
}
使用GCC 8在我的Linux x86_64上输出:

$。/dummy
一:-1266441984.000000
i32:-1266441984.000000
u32:3028525312.000000
李:5062500000000.000000
i64:5062500000000.000000
u64:5062500000000.000000
整数溢出:

#包括
#包括
#包括
int main(int argc,char*argv[]){
int i=1500;
int32_t i32=1500;
uint32_t u32=1500;
printf(“i:%lf\n”,(双精度)(i*i*i*i));
printf(“i32:%lf\n”(双精度)(i32*i32*i32*i32*i32));
printf(“u32:%lf\n”(双精度)(u32*u32*u32*u32*u32));
长整数li=1500;
int64_t i64=1500;
uint64_t u64=1500;
printf(“li:%lf\n”,双精度)(li*li*li*li));
printf(“i64:%lf\n”,(双精度)(i64*i64*i64*i64*i64));
printf(“u64:%lf\n”,(双精度)(u64*u64*u64*u64*u64));
返回(0);
}
使用GCC 8在我的Linux x86_64上输出:

$。/dummy
一:-1266441984.000000
i32:-1266441984.000000
u32:3028525312.000000
李:5062500000000.000000
i64:5062500000000.000000
u64:5062500000000.000000

i*i*i*i
-这就是“给出负面结果”的含义。你听说过整数溢出吗?调试提示:使用
%e“
%a“
%g”
都比
%lf”
更具信息性。是的,我现在知道了。谢谢您,Eugene1500**4=506250000000=0x4 9A B4 83 A1 00,因此只有当
int
是64位整数时,这才有效,否则将导致溢出。然后将剩余部分转换为
double
i*i*i
——这就是“给出否定结果”的原因。你听说过整数溢出吗?调试提示:使用
%e“
%a“
%g”
都比
%lf”
更具信息性。是的,我现在知道了。谢谢您,Eugene1500**4=506250000000=0x4 9A B4 83 A1 00,因此只有当
int
是64位整数时,这才有效,否则将导致溢出。剩余部分随后转换为
双精度