代码之家  ›  专栏  ›  技术社区  ›  Frank Ridder

在C中交换双精度数字[重复]

  •  2
  • Frank Ridder  · 技术社区  · 7 年前

    54321.987 我想把第2位和第4位互换,输出应该是 52341.987

    太小时的示例: 12.34 1002.34 .

    7 回复  |  直到 7 年前
        1
  •  1
  •   ryyker    7 年前

    使用字符串化方法:
    还有更优雅的方法,但您可以看到该伪代码的步骤(并对其进行改进),以字符串化、移动值并转换回数字。

    char buf1[20];
    char buf2[20];
    char *dummy;
    double val = 54321.987;
    
    sprintf(buf1, "%9.3f", val );
    //Now the number is in string form: "54321.987".  Just move the two elements  
    buf2[0]=buf1[0];
    buf2[1]=buf1[3];
    buf2[2]=buf1[2];
    buf2[3]=buf1[1]; //and so on
    //now convert back:
    
    val = strtod(buf2, &dummy);
    printf("%9.3f\n", val);
    

    double swap_num_char(double num, int precision, int c1, int c2); //zero index for c1 and c2
    
    
    int main(void)
    {
    
        double val = 54321.987;
    
        printf("%9.3f\n", swap_num_char(val, 3, 1, 3));
    
        return 0;   
    }
    
    double swap_num_char(double num, int precision, int c1, int c2)
    {
        char buf[25]; 
        char format[10];
        char *dummy;
        char c;
    
        sprintf(format, "%s0.%df", "%", precision);
    
        sprintf(buf, format, num);
    
        c = buf[c1];
        buf[c1] = buf[c2];
        buf[c2] = c;
    
        num = strtod(buf, &dummy);
    
        return num;
    }
    
        2
  •  0
  •   abelenky    7 年前

    您可以通过简单的操作获得感兴趣的两位数:

    double x = 54321.987;
    double tens = ((int)(x / 10)) % 10;        // Result is 2
    double thousands = ((int)(x / 1000)) % 10; // Result is 4
    

    然后你可以从原始位置减去数字, 并将其添加回新位置:

    x = x - (tens * 10.0) - (thousands * 1000.0); // result is 50301.987
    x = x + (tens * 1000.0) + (thousands * 10.0); // result is 52341.987
    

    现在只需减少表达式:

    x = x + tens * (1000.0 - 10.0) - thousands * (1000.0 - 10.0);
    

    x += (tens - thousands) * 990.0;
    

    x += (((int)(x/10))%10 - ((int)(x/1000))%10) * 990;
    
        3
  •  0
  •   user3458 user3458    7 年前

    您可以使用floor()提取数字(至少从正数中提取):

    int place1 = 1; /* 0-based*/
    double desiredPowerOf10 = powersOf10[place1];
    double nextPowerOf10 = powersOf10[place1 + 1];
    double digit1 = floor(number / desiredPowerOf10) - floor(number/nextPowerOf10) * 10;
    

    double digitsRemoved = number - (digit1 * power1 + digit2 * power2);
    double digitsSwapped = digitsRemoved + digit1 * power2 + digit2 * power1;
    

    然而,这可能会因数字过大而导致精度下降。

        4
  •  0
  •   chux    7 年前

    1-使用 modf() 把数字分成整数和小数部分。

    double modf(double value, double *iptr);
    

    modf 函数打断参数 value 分为整数部分和分数部分,C11§7.12.6.12

    3-重建

    #include <float.h>
    #include <math.h>
    #include <stdio.h>
    
    double swap2_4digit(double x) {
      if (signbit(x)) {
        return -swap2_4digit(-x);
      }
      printf("Before %f\n", x);
      double ipart;
      double fpart = modf(x, &ipart);
      //       ms_digit    digits  '.'  '\0'  min_size  
      char buf[1 + DBL_MAX_10_EXP + 1 +  1   + 4];  // Insure buffer is big enough
    
      strcpy(buf, "0000");  // Handle small numbers
      sprintf(buf + strlen(buf), "%.0f", ipart);
      size_t len = strlen(buf);
      char ch = buf[len - 2];
      buf[len - 2] = buf[len - 4];
      buf[len - 4] = ch;
    
      x = atof(buf) + fpart;
      printf("After  %f\n", x);
      return x;
    }
    
    int main(void) {
      swap2_4digit(54321.987);
      swap2_4digit(12.34);
    }
    

    Before 54321.987000
    After  52341.987000
    Before 12.340000
    After  1002.340000
    

    为运算留下的东西。对其他数字位置进行概述。

        5
  •  0
  •   Mandar Sadye    7 年前

    如果希望输入数字加倍,则可以执行以下操作:

        #include <stdio.h>
        #include <stdlib.h>
    
        int main()
        {
            double numbergiven = 56789.1234;
            double dummy;
            double _4th_digit = (10*modf(numbergiven/10000, &dummy)) - modf(numbergiven/1000, &dummy);
            double _2th_digit = (10*modf(numbergiven/100, &dummy)) - modf(numbergiven/10, &dummy);
            numbergiven = numbergiven - (_4th_digit * 1000) + (_2th_digit * 1000);
            numbergiven = numbergiven + (_4th_digit * 10) - (_2th_digit * 10);
            printf("%lf",numbergiven);
            return 0;
        }
    

    如果您不熟悉modf,那么您可以简单地这样做:

        #include <stdio.h>
        #include <stdlib.h>
    
        int main()
        {
            double numbergiven = 56789.1234;
            int number = numbergiven;
            int _4th_digit = (number/1000) - (10*(number/10000));
            int _2th_digit = (number/10) - (10*(number/100));
            numbergiven = numbergiven - (_4th_digit * 1000) + (_2th_digit * 1000);
            numbergiven = numbergiven + (_4th_digit * 10) - (_2th_digit * 10);
            printf("%lf",numbergiven);
            return 0;
        }
    
        6
  •  0
  •   chux    7 年前

    fmod() @John Bollinger

    这个 fmod 函数计算 x/y .

    用10进行修改 位置-1

    减去这两个数字,然后将其相加。

    double swap_digit(double x, unsigned a, unsigned b) {
      printf("Before %f\n", x);
      double a_place = pow(10.0, a);
      double b_place = pow(10.0, b);
      double scaled_digit_a = fmod(x, a_place) - fmod(x, a_place/10);
      double scaled_digit_b = fmod(x, b_place) - fmod(x, b_place/10);
      x -= scaled_digit_a + scaled_digit_b;
      x += scaled_digit_a/a_place*b_place + scaled_digit_b/b_place*a_place;
      printf("After  %f\n", x);
      return x;
    }
    
    int main(void) {
      swap_digit(54321.987,2,4);
      swap_digit(12.34,2,4);
    }
    

    输出

    Before 54321.987000
    After  52341.987000
    Before 12.340000
    After  1002.340000
    
        7
  •  0
  •   boriaz50    7 年前

    double 变量,您可能不会收到原始数字,因为 floating-point arithmetic .

    因此,应该使用double的字符串表示进行操作。主要方面是字符串将包含多少个数字。但很明显,你们从输入中得到数字。将其扫描为字符串,而不是 双重的 .

    有一个工作代码:

    #include <stdio.h>
    #include <stddef.h>
    
    #define BUFSIZE 255
    
    void swap_digits(char *str, int n, int m) {
        char *digit1 = NULL;
        char *digit2 = NULL;
    
        int count = 0;
        while (*str && (!digit1 || !digit2)) {
            if (*str != '.') {
                count++;
                if (count == n) {
                    digit1 = str;
                }
                if (count == m) {
                    digit2 = str;
                }
            }
    
            str++;
        }
    
        if (digit1 && digit2) {
            char tmp = *digit1;
            *digit1 = *digit2;
            *digit2 = tmp;
        }
    }
    
    int main(void) {
        char buffer[BUFSIZE];
        scanf("%s", buffer);
    
        // it is preferably to validate input
    
        swap_digits(buffer, 2, 4);
        printf(buffer);
        return 0;
    }