Приведение к int некорректно работает - C (СИ)
Формулировка задачи:
Блин, не могу уловить момент из-за чего приведение к целому "хромает"...
В цикле делю вещественное "123." на 10, получаю целую и дробную часть.
Далее отбираю целую часть и снова в цикл деления на 10, а дробную часть умножаю на 10 и результат пытаюсь привести к int.
Ожидаю получить "3", "2" и "1", а выходит "3", "1" и "1".
Прошу помощи.
#include <stdio.h>
#include <stdlib.h>
void main() {
double num=123., part_i, part_f;
while (!num<1) {
num = num/10;
part_i = (int)num;
part_f = num-part_i;
printf("num=%lf\n",num);
printf("part_i_=%lf\n",part_i);
printf("part_f_=%lf\n",part_f);
// целая часть корректна: "3.", "2." и "1."
printf("part_f*10=%lf\n",part_f*10);
// целая часть приведена к int некорректно: "3", "1" и "1" ???
printf("(int)(part_f*10)=%d\n",(int)(part_f*10));
num = part_i;
}
}Решение задачи: «Приведение к int некорректно работает»
textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
void main() {
int k=0, i=0, ndx=0, bNegative=0;
double num, part_i, part_f;
char tmp, *str=(char*)calloc(10,sizeof(char));
printf("Input integer number... ");
scanf("%lf",&num);
if (num<0) {
bNegative = 1;
num = -num;
k++;
}
while (!num<1) {
num = num/10;
part_i = (int)num;
part_f = num-part_i;
printf("num=%lf\n",num);
printf("part_i=%lf\n",part_i);
printf("part_f=%lf\n",part_f);
printf("(part_f*10)=%lf\n",part_f*10);
//str[ndx] = 48 + part_f*10;
//
// работает корректно: в цикле получаем "3", "2" и "1"
// но принципаильно пытаюсь избавиться от варнинга
// warning C4244: '=' : conversion from 'double' to 'char', possible loss of data
str[ndx] = 48 + (int)(part_f*10);
//
// пытаясь "избавиться от варнинга"
// warning C4244: '=' : conversion from 'double' to 'char', possible loss of data
// прихожу к тому, что
// работает некорректно: в цикле получаем "3", "1" и "1"
// казалось бы, просто выделяем целую часть из явно круглого значения...
printf("str[%d]="%c"\n",ndx,str[ndx]);
num = part_i;
ndx++;
k++;
}
if (bNegative) {
str[ndx] = '-';
}
while ((k/2-i)>=1) {
tmp = str[i];
str[i] = str[k-1-i];
str[k-1-i] = tmp;
i++;
}
printf("str="%s"\n",str);
}
Объяснение кода листинга программы
- В начале кода объявлены переменные: k, i, ndx, bNegative и str.
- Затем пользователю предлагается ввести целое число.
- Далее идет проверка, является ли введенное число отрицательным.
- Если число отрицательное, то его делают положительным, увеличивают счетчик k и присваивают -1 переменной bNegative.
- Затем начинается цикл, который продолжается, пока введенное число больше или равно 1.
- В каждой итерации цикла число разбивается на целую и дробную части.
- Целая часть сохраняется в переменной part_i, а дробная в переменной part_f.
- Затем идет попытка присвоить дробную часть числа, умноженную на 10, элементу массива str с индексом ndx.
- Ошибка C4244 предупреждает о возможной потере данных при преобразовании double в char.
- Попытка избавиться от этого предупреждения приводит к тому, что в цикле получаются числа
3,1и1. - Затем идет цикл, который переворачивает строку str.
- В конце выводится полученная строка.