в каких случаях происходит исключение с плавающей запятой, отличное от деления на ноль?

#c #floating-point-exceptions

#c #исключения с плавающей запятой

Вопрос:

я писал некоторый код, чтобы проверить контрольную сумму для кредитной карты с помощью алгоритма, известного как алгоритм Луна, и проверить, является ли это действительным номером карты или нет, код, который я написал, программа скомпилирована нормально, но когда я ввел данные, в них говорилось об исключении с плавающей запятой, я немного изучил, когда вызывается исключение с плавающей запятой, но был только один случай, в котором говорилось, что это происходит, когда вы делите на ноль, но моя программа этого не делает, поэтому я хочу знать, какие другие случаи могут возникнуть, которые приводят к исключению с плавающей запятой.

 #include lt;stdio.hgt; int main(void) {  int a = get_int("enter your card number:");  int x = 1 ;  int z ;  int y = 0 ;  int s = 0 ;  int d,k,m,g,h;  int c ;  int f = 1;  int p = 0;  bool checksum ;  int l ;  while ((a / (10^x) )gt; 1)  {  c = (a/10^x) ;  z= c % 10 ;  k = 2*z ;  if (klt;10)  {  d = k;  }  else if (kgt;10||k==10)  {  d = (k) ;  }  y  =d;  x =2;  }  x=p;  while ( (a / (10 ^ x) )gt;1 )   {  l= a/(10^x);  m = l % 10 ;  s  = m;  x =2;  }  g= s y;  if(g==0)  {  checksum = 1 ;  printf("valid");  }  else  {  checksum = 0 ;   printf("invalid");  } }```     

Комментарии:

1. ‘(10^x)’ оператор со стрелкой вверх не является экспоненцией.

2. that it occurs when you divide by zero but my program does not do that откуда ты знаешь? a / (10 ^ x) наверняка выглядит как деление на 0, когда x = 10 .

3. «моя программа этого не делает» ну, вы должны создать резервную копию этого утверждения, загрузив каждый делитель в временный параметр, прежде чем использовать его, а затем либо распечатайте его, либо используйте отладчик для проверки значения.

4. (a) В C — ^ побитовый оператор XOR. (б) Когда x равно 10, x^10 равно нулю, поэтому a / (10 ^ x) делится на ноль. (c) По историческим причинам целочисленное деление на ноль сообщается в сигнале об исключении с плавающей запятой. (d) По другим историческим причинам исключения с плавающей запятой в значительной степени подавляются, и предоставляются альтернативные результаты (например, NaN). Исключения включают недопустимую операцию (нет полезного определимого результата), деление на ноль, переполнение (превышен конечный диапазон), недостаточный поток (превышен нормальный диапазон) и неточность (ограниченная точность формата не может представлять идеальный математический результат).

5. @dxuian: Другие языки имеют другие правила и ^ не выполняли возведение в степень ни в одной из ваших предыдущих программ на языке Си.

Ответ №1:

По моему мнению, вы думаете , что 10 в степени x записано в C как 10^x , но ничего более далекого от этого. 10^x действительно 10 x или x (побитовое исключающее или) , а не a в зависимости от мощности оператора. Так что, если x окажется, что 10, вы получите 0 в качестве знаменателя выражение, и вы действительно будете делить на ноль.

В любом случае, я думаю, что вам будет легче обрабатывать ввод, если вы действительно примете строку цифр вместо целого числа. Поскольку целочисленные числа имеют ограниченную точность, использование an int приведет к ограничению диапазона чисел от 0 до 4 204 967 295, в то время как кредитная карта содержит от 15 до 20 цифр, это может сделать диапазон чисел недостаточным для обработки одного номера карты.

С другой стороны, если вы проанализируете свой код, вы увидите, что в вашей программе не используется плавающая точка (ни деление, ни какая-либо другая операция). Это связано с тем, что целочисленное деление приводит к тому же исключению, что и деление с плавающей запятой на ноль. Оба сигнализируются с одним и тем же исключением, несмотря на причину исключения.