回答
使用字符串化的方法:
有更优雅的方式,但可以看到的步骤(和改善)这个伪代码字符串化,移动值,并将其转换回数字。
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;
}
如果你想输入数字双待,那么你可以做这样的事情:
#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;
}
@chux我刚刚根据你的建议编辑了代码,是否有新的错误? –
我认为用双傀儡会更清楚; double _4th_digit =(10 * modf(numbergiven/10000,&dummy)) - modf(numbergiven/1000,&dummy);' – chux
你可以得到两个数字,你有兴趣与简单的操作:
您可以
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;
细节'(int)(x/10)'是UB的大'双'。 OP可能不关心所有'double'的代码。 – chux
一个解决办法是提取数字,然后交换他们。
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;
通过使用地板()提取数字(至少从正数)
虽然这可能会导致精度损失非常大的数字。
1 - 使用modf()
将数字拆分为整数和小数部分。
double modf(double value, double *iptr);
的
modf
功能打破参数value
分为整数和小数部分,C11§7.12.6.12
2 - 打印整数部分作为一个字符串,并执行交换。
3 - 重建离开OP
#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
东西。做一般的其他数字位置。
Double以位序列的形式存储在存储器中,但您希望使用十进制数字进行操作。这样做与double
变量您可能不会收到原始数字,因为floating-point arithmetic。
因此,您应该使用double的字符串表示进行操作。主要方面是多少个数字字符串将包含。但很明显,你从输入中得到数字。扫描它作为字符串,而不是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;
}
或使用fmod()
@John Bollinger。
fmod
函数计算x/y
的浮点剩余部分。
提取2位每改装的具有10 地方差和改装用10 地方-1。
减去2位数字,然后将它们添加回交换。
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
- 1. 在C++中交换双倍数据位
- 2. 双字节交换
- 3. C交换双向链表
- 4. C++ 32位字的字节交换
- 5. 如何字节交换双?
- 6. 根据其位置交换数字的任意两位数字
- 7. C++字符串双转换
- 8. 在C中双向链表中交换节点#
- 9. 在数组中交换位置
- 10. 从Combobox双位数转换为int双位数
- 11. 在Objective-C中交换字节顺序?
- 12. 字节交换和C++/C
- 13. 字节数组在C#中的双重转换#
- 14. Ç40位字节交换(端)
- 15. 双引号字符串替换在C#
- 16. 在Visual Studio中将字节数组中的64位双精度型转换为80位双精度型
- 17. 交换数字
- 18. 交换字节中的每一位
- 19. 交换C中某个单词的字符串位置?
- 20. 在C++中使用2d数组交换
- 21. 在C++类中重载交换函数
- 22. 在C中转换一个双重字符到一个字符#
- 23. 在C++中优化字符数组成员交换
- 24. C++交换字符串
- 25. 转换双为int在C + +
- 26. 在git中将双亲提交转换为单亲提交
- 27. javascript中的双字节数组转换
- 28. 字符交换在一个文件C++
- 29. Java递归和整数双位数字
- 30. VIM:在双引号内交换json值
字符串化它。交换字符,解开它。 sprintf(),sscanf()。 –
如果它是一个编程任务,并且您不想将其串化。首先在提醒时使用模10功能提取所有数字。 然后检查相应的第2位和第4位。 例如:n = 12345.678。使用'n-n%1'提取小数部分 用'n-n%10'获取最后一位数字,然后用n除以10,同样得到下一位数字,依此类推。 –
..或者你可以用mult/div重复10次做一些明确的,讨厌的loopy/recursivey事情。 –