Приведение к 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);
}

Объяснение кода листинга программы

  1. В начале кода объявлены переменные: k, i, ndx, bNegative и str.
  2. Затем пользователю предлагается ввести целое число.
  3. Далее идет проверка, является ли введенное число отрицательным.
  4. Если число отрицательное, то его делают положительным, увеличивают счетчик k и присваивают -1 переменной bNegative.
  5. Затем начинается цикл, который продолжается, пока введенное число больше или равно 1.
  6. В каждой итерации цикла число разбивается на целую и дробную части.
  7. Целая часть сохраняется в переменной part_i, а дробная в переменной part_f.
  8. Затем идет попытка присвоить дробную часть числа, умноженную на 10, элементу массива str с индексом ndx.
  9. Ошибка C4244 предупреждает о возможной потере данных при преобразовании double в char.
  10. Попытка избавиться от этого предупреждения приводит к тому, что в цикле получаются числа 3, 1 и 1.
  11. Затем идет цикл, который переворачивает строку str.
  12. В конце выводится полученная строка.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 4 из 5