Форум программистов, компьютерный форум CyberForum.ru

Парсинг и валидация записи числа - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
04.01.2013, 10:16     Парсинг и валидация записи числа #1
Дана запись числа:
Все дробные числа пишутся в знаковом десятичном формате с плавающей запятой со знаковым порядком. Знак + числа в целом опускается. Если число равно нолю, то: знак числа в целом опускается, а порядок равен нолю. Знак порядка опускается только, если порядок равен нолю. Разделитель мантиссы и порядка – буква "E" верхнего регистра. Разделитель целой и дробной части мантиссы – точка.
, требуется выполнить её валидацию и вернуть double в значении функции и код ошибки через параметр. Как нибудь я это распарсю, вопрос в том, как сделать лучше и как сделать валидацию.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
05.01.2013, 14:07  [ТС]     Парсинг и валидация записи числа #21
Цитата Сообщение от iifat Посмотреть сообщение
В sliceInt -- она там тоже есть.
Не пойдёт, дробную часть мантиссы так не распарсишь, проблема в том, что слайсоинт вернёт инт, а его будет не понятно, на что делить.

Добавлено через 5 минут
Цитата Сообщение от iifat Посмотреть сообщение
Можно, и не одним способом, и совершенно различной подробности. Один из способов я тебе даже набросал. Не самый лучший, разумеется -- лучшие гораздо сложнее.
Цитата Сообщение от iifat Посмотреть сообщение
after_p * 0.1 ^ (p-p0);
Зачем ксорить разность с константой? К тому же разность имеет разрядность типа size_t, а константа типа double, они могут не совпадать.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
05.01.2013, 14:13  [ТС]     Парсинг и валидация записи числа #22
Во вложении полная спецификация, глотать не валидное нельзя категорически, выдача кода ошибки только желательна, подробности не требуются, в первом посте подзадача в задаче парсинга всего файла.
Вложения
Тип файла: rar Формат xsm версии 00000000.rar (4.5 Кб, 3 просмотров)
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
05.01.2013, 15:08  [ТС]     Парсинг и валидация записи числа #23
Точка - единственный, помимо места в файле, надёжный признак, различающий здесь две системы счисления, так как целое может быть и 000025E0, а ни 0x, ни h малое, ни 16 в скобках рядом с числом нет. А вот 00025.0E0 - это уже точно не шестнадцатеричное. Фатальная же гога как раз не так страшна, как избыточная всеядность.

Добавлено через 47 минут
А так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
double ParseDouble(const
                   std::string     &Buffer,
                   TParseXSMResult &ResultCode)
{
 double        Result;
 double        d;
 size_t        re;
 size_t        de;
 size_t        i;
 size_t        L;
 size_t        p;
 size_t        e;
 size_t        e1;
 unsigned char c;
 ResultCode=TPXSMRNoError;
 Result=0.0;
 if (Buffer=="0.0E+0")
 {
  return 0.0;
 }
 L=Buffer.length();
 for (p=L, i=2; i<L; ++i)
 {
  c=Buffer[i];
  if (c=='.')
  {
   p=i;
   break;
  }
 }
 if (p==L)
 {
  default : ResultCode|=TPXSMRParseError;
  return Result;
 }
 for (e=L, i=p+2; i<L; ++i)
 {
  c=Buffer[i];
  if (c=='E')
  {
   p=i;
   break;
  }
 }
 if (e==L)
 {
  default : ResultCode|=TPXSMRParseError;
  return Result;
 }
 e1=e+1;
 if ((L-e)<3)
 {
  if (Buffer.substr(e, L-e)!="E0")
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 else
 {
  c=Buffer[e1];
  if ((c!='-')&&(c!='+'))
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 Result=0.0;
 for (d=0.1, i=p+1; i<e; ++i, d/=10.0)
 {
  c=Buffer[i];
  if ((c>='0')&&(c<='9'))
  {
   Result+=d*((double)(c-(unsigned char)'0'));
  }
  else
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 for (d=1.0, i=p-1; i>0; ++i, d*=10.0)
 {
  c=Buffer[i];
  if ((c>='0')&&(c<='9'))
  {
   Result+=d*((double)(c-(unsigned char)'0'));
  }
  else
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 c=Buffer[i];
 switch (c)
 {
  case '-': Result=-Result;
  break;
  case '+': Result=-Result;
  break;
  default : ResultCode|=TPXSMRParseError;
  return Result;
 }
 er=1;
 for (de=1, i=L-1; i>e1; --i)
 {
  c=Buffer[i];
  if ((c>='0')&&(c<='9'))
  {
   er+=de*((size_t)(c-(unsigned char)'0'));
  }
  else
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 c=Buffer[e1];
 if (c=='-')
 {
  for (; re>0; --re)
  {
   Result/=10.0;
  }
 }
 else
 {
  for (; re>0; --re)
  {
   Result*=10.0;
  }
 }
 return Result;
}
? Есть ещё дыры в валидации? А лишние операции?
iifat
2179 / 1332 / 96
Регистрация: 05.06.2011
Сообщений: 3,692
05.01.2013, 16:02     Парсинг и валидация записи числа #24
Цитата Сообщение от taras atavin Посмотреть сообщение
Зачем ксорить разность с константой?
Хотел написать возведение в степень. Забыл, как оно в Цэ пишется.

Добавлено через 10 минут
100.0E+2 -- это правильное число, как я понял? Твоя прога не съест. Из-за опущенного + в начале.

Добавлено через 7 минут
С 105 строки кая-то ересь пошла. Ты ж умеешь читать целое число (строки 82-93). Повтори, если уж так не любишь выделять подпрограммы. И, кстати, похоже, порядок (после E) у тебя сначала er, а с 122 -- re. Ну и, напоследок, для умножения на 10 в степени ха есть гораздо более приятные методы, чем цикл от 1 до ха.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
05.01.2013, 16:37  [ТС]     Парсинг и валидация записи числа #25
Цитата Сообщение от iifat Посмотреть сообщение
Хотел написать возведение в степень. Забыл, как оно в Цэ пишется.
Ни как, только делить/умножать. В крайнем случае вызвать функцию, в которой опять таки будет деление/умножение. Если, конечно, показатель целый. Для действительного можно
C++
1
exp(n*ln(a));
, или функцию, в которой внутри опять
C++
1
return exp(n*ln(a));
.

Добавлено через 2 минуты
Цитата Сообщение от iifat Посмотреть сообщение
100.0E+2 -- это правильное число, как я понял? Твоя прога не съест.
Не правильное.

Добавлено через 2 минуты
Цитата Сообщение от iifat Посмотреть сообщение
Ну и, напоследок, для умножения на 10 в степени ха есть гораздо более приятные методы, чем цикл от 1 до ха.
Это какие же? Оператора возведения в степень нет.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
double ParseDouble(const
                   std::string     &Buffer,
                   TParseXSMResult &ResultCode)
{
 double        Result;
 double        d;
 size_t        re;
 size_t        de;
 size_t        i;
 size_t        L;
 size_t        p;
 size_t        e;
 size_t        e1;
 unsigned char c;
 ResultCode=TPXSMRNoError;
 Result=0.0;
 if (Buffer=="0.0E+0")
 {
  return 0.0;
 }
 L=Buffer.length();
 for (p=L, i=2; i<L; ++i)
 {
  c=Buffer[i];
  if (c=='.')
  {
   p=i;
   break;
  }
 }
 if (p==L)
 {
  default : ResultCode|=TPXSMRParseError;
  return Result;
 }
 for (e=L, i=p+2; i<L; ++i)
 {
  c=Buffer[i];
  if (c=='E')
  {
   p=i;
   break;
  }
 }
 if (e==L)
 {
  default : ResultCode|=TPXSMRParseError;
  return Result;
 }
 e1=e+1;
 if ((L-e)<3)
 {
  if (Buffer.substr(e, L-e)!="E0")
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 else
 {
  c=Buffer[e1];
  if ((c!='-')&&(c!='+'))
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 Result=0.0;
 for (d=0.1, i=p+1; i<e; ++i, d/=10.0)
 {
  c=Buffer[i];
  if ((c>='0')&&(c<='9'))
  {
   Result+=d*((double)(c-(unsigned char)'0'));
  }
  else
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 for (d=1.0, i=p-1; i>0; ++i, d*=10.0)
 {
  c=Buffer[i];
  if ((c>='0')&&(c<='9'))
  {
   Result+=d*((double)(c-(unsigned char)'0'));
  }
  else
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 c=Buffer[i];
 switch (c)
 {
  case '-': Result=-Result;
  break;
  case '+': Result=-Result;
  break;
  default : ResultCode|=TPXSMRParseError;
  return Result;
 }
 re=1;
 for (de=1, i=L-1; i>e1; --i)
 {
  c=Buffer[i];
  if ((c>='0')&&(c<='9'))
  {
   re+=de*((size_t)(c-(unsigned char)'0'));
  }
  else
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 c=Buffer[e1];
 if (c=='-')
 {
  for (; re>0; --re)
  {
   Result/=10.0;
  }
 }
 else
 {
  for (; re>0; --re)
  {
   Result*=10.0;
  }
 }
 return Result;
}
.

Добавлено через 1 минуту
Цитата Сообщение от iifat Посмотреть сообщение
если уж так не любишь выделять подпрограммы.
У меня и так хватает подпрограмм.

Добавлено через 2 минуты
Цитата Сообщение от iifat Посмотреть сообщение
С 105 строки кая-то ересь пошла.
В чём ересь?

Добавлено через 10 минут
Дефалты чего то остались.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
double ParseDouble(const
                   std::string     &Buffer,
                   TParseXSMResult &ResultCode)
{
 double        Result;
 double        d;
 size_t        re;
 size_t        de;
 size_t        i;
 size_t        L;
 size_t        p;
 size_t        e;
 size_t        e1;
 unsigned char c;
 ResultCode=TPXSMRNoError;
 Result=0.0;
 if (Buffer=="0.0E+0")
 {
  return 0.0;
 }
 L=Buffer.length();
 for (p=L, i=2; i<L; ++i)
 {
  c=Buffer[i];
  if (c=='.')
  {
   p=i;
   break;
  }
 }
 if (p==L)
 {
  ResultCode|=TPXSMRParseError;
  return Result;
 }
 for (e=L, i=p+2; i<L; ++i)
 {
  c=Buffer[i];
  if (c=='E')
  {
   p=i;
   break;
  }
 }
 if (e==L)
 {
  ResultCode|=TPXSMRParseError;
  return Result;
 }
 e1=e+1;
 if ((L-e)<3)
 {
  if (Buffer.substr(e, L-e)!="E0")
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 else
 {
  c=Buffer[e1];
  if ((c!='-')&&(c!='+'))
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 Result=0.0;
 for (d=0.1, i=p+1; i<e; ++i, d/=10.0)
 {
  c=Buffer[i];
  if ((c>='0')&&(c<='9'))
  {
   Result+=d*((double)(c-(unsigned char)'0'));
  }
  else
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 for (d=1.0, i=p-1; i>0; ++i, d*=10.0)
 {
  c=Buffer[i];
  if ((c>='0')&&(c<='9'))
  {
   Result+=d*((double)(c-(unsigned char)'0'));
  }
  else
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 c=Buffer[i];
 switch (c)
 {
  case '-': Result=-Result;
  break;
  case '+': Result=-Result;
  break;
  default : ResultCode|=TPXSMRParseError;
  return Result;
 }
 re=1;
 for (de=1, i=L-1; i>e1; --i)
 {
  c=Buffer[i];
  if ((c>='0')&&(c<='9'))
  {
   re+=de*((size_t)(c-(unsigned char)'0'));
  }
  else
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 c=Buffer[e1];
 if (c=='-')
 {
  for (; re>0; --re)
  {
   Result/=10.0;
  }
 }
 else
 {
  for (; re>0; --re)
  {
   Result*=10.0;
  }
 }
 return Result;
}
Добавлено через 11 минут
Дополнил спецификацию:
Все дробные числа пишутся в знаковом десятичном формате с плавающей запятой со знаковым порядком. Знак + числа в целом опускается. Если число равно нолю, то: знак числа в целом опускается, а порядок равен нолю. Знак порядка опускается только, если порядок равен нолю. Знак числа опускается, только если оно равно нолю. Разделитель мантиссы и порядка – буква "E" верхнего регистра. Разделитель целой и дробной части мантиссы – точка.
.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
05.01.2013, 18:08     Парсинг и валидация записи числа #26
Для записи "спецификаций" грамматик уже давно придумана (Р)БНФ же:
дробное-число ::= [знак] мантисса [порядок]
мантисса ::= натуральное-число [точка [натуральное-число]]
порядок ::= обозначение-порядка знак натуральное-число | обозначение-порядка 0
натуральное-число ::= цифра {цифра}
знак ::= + |
обозначение-порядка ::= e | E
точка ::= .
цифра ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Добавлено через 11 минут
Ну или
дробное-число ::= 0 E 0 | мантисса порядок
мантисса ::= [] натуральное-число | (+ | ) неотрицательное-целое-число . неотрицательное-целое-число
порядок ::= E (+ | ) натуральное-число | E 0
неотрицательное-целое-число ::= цифра {цифра}
натуральное-число ::= ненулевая-цифра {цифра}
цифра ::= 0 | ненулевая-цифра
ненулевая-цифра ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
для ваших требований, как я понял.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
05.01.2013, 18:22  [ТС]     Парсинг и валидация записи числа #27
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
дробное-число ::= [знак] мантисса [порядок]
мантисса ::= натуральное-число [точка [натуральное-число]]
порядок ::= обозначение-порядка знак натуральное-число | обозначение-порядка 0
натуральное-число ::= цифра {цифра}
знак ::= + | –
обозначение-порядка ::= e | E
точка ::= .
цифра ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Тогда уж так:
"действительное число::=0.0E0 | знак целая часть точка дробная часть E порядок
знак ::= + | -
целая часть ::= цифра {цифра}
дробная часть ::= цифра {цифра}
порядок ::=0 | знак порядка цифра {цифра}
знак порядка :: + | -"
И почему слово "спецификаций" взято в кавычки? Это не язык и не клавиатурный ввод, а файловый формат.
iifat
2179 / 1332 / 96
Регистрация: 05.06.2011
Сообщений: 3,692
05.01.2013, 18:24     Парсинг и валидация записи числа #28
Цитата Сообщение от taras atavin Посмотреть сообщение
В чём ересь?
Ну, сравни же в 82-й! Result ты начинаешь с нуля -- почему re = 1? И где de *= 10?
Цитата Сообщение от taras atavin Посмотреть сообщение
Знак + числа в целом опускается
Вот это о чём? Положительные числа можно писать без + спереди? Если таки да, то самый первый символ ты на цифру не проверяешь -- только + и -.
И таки уточни, ей богу, насчёт степени. Ну обязана ж она быть!
А вот фиг. Нету. Забыл. Ну, тогда вроде всё. Может, разве что защиту от переполнения стоило б вставить, тут уже писали...
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
05.01.2013, 18:35  [ТС]     Парсинг и валидация записи числа #29
И в другом месте, но в том же документе будет
"целое число ::= цифра цифра цифра цифра цифра цифра цифра цифра
цифра ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F". Имхо будет путаница.

Добавлено через 1 минуту
Цитата Сообщение от iifat Посмотреть сообщение
Положительные числа можно писать без + спереди?
Нельзя. Без знака пишется только ноль.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
double ParseDouble(const
                   std::string     &Buffer,
                   TParseXSMResult &ResultCode)
{
 double        Result;
 double        d;
 size_t        re;
 size_t        de;
 size_t        i;
 size_t        L;
 size_t        p;
 size_t        e;
 size_t        e1;
 unsigned char c;
 ResultCode=TPXSMRNoError;
 Result=0.0;
 if (Buffer=="0.0E+0")
 {
  return 0.0;
 }
 L=Buffer.length();
 for (p=L, i=2; i<L; ++i)
 {
  c=Buffer[i];
  if (c=='.')
  {
   p=i;
   break;
  }
 }
 if (p==L)
 {
  ResultCode|=TPXSMRParseError;
  return Result;
 }
 for (e=L, i=p+2; i<L; ++i)
 {
  c=Buffer[i];
  if (c=='E')
  {
   p=i;
   break;
  }
 }
 if (e==L)
 {
  ResultCode|=TPXSMRParseError;
  return Result;
 }
 e1=e+1;
 if ((L-e)<3)
 {
  if (Buffer.substr(e, L-e)!="E0")
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 else
 {
  c=Buffer[e1];
  if ((c!='-')&&(c!='+'))
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 Result=0.0;
 for (d=0.1, i=p+1; i<e; ++i, d/=10.0)
 {
  c=Buffer[i];
  if ((c>='0')&&(c<='9'))
  {
   Result+=d*((double)(c-(unsigned char)'0'));
  }
  else
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 for (d=1.0, i=p-1; i>0; ++i, d*=10.0)
 {
  c=Buffer[i];
  if ((c>='0')&&(c<='9'))
  {
   Result+=d*((double)(c-(unsigned char)'0'));
  }
  else
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 c=Buffer[i];
 switch (c)
 {
  case '-': Result=-Result;
  break;
  case '+': Result=-Result;
  break;
  default : ResultCode|=TPXSMRParseError;
  return Result;
 }
 re=0;
 for (de=1, i=L-1; i>e1; --i, de*=10)
 {
  c=Buffer[i];
  if ((c>='0')&&(c<='9'))
  {
   re+=de*((size_t)(c-(unsigned char)'0'));
  }
  else
  {
   ResultCode|=TPXSMRParseError;
   return Result;
  }
 }
 c=Buffer[e1];
 if (c=='-')
 {
  for (; re>0; --re)
  {
   Result/=10.0;
  }
 }
 else
 {
  for (; re>0; --re)
  {
   Result*=10.0;
  }
 }
 return Result;
}
Добавлено через 14 секунд
Цитата Сообщение от iifat Посмотреть сообщение
у, сравни же в 82-й! Result ты начинаешь с нуля -- почему re = 1? И где de *= 10?
Исправил.

Добавлено через 3 минуты
Цитата Сообщение от iifat Посмотреть сообщение
Сообщение от taras atavin
Знак + числа в целом опускается
Осталось с ранней версии, исправил:
Все дробные числа пишутся в знаковом десятичном формате с плавающей запятой со знаковым порядком. Если число равно нолю, то: знак числа в целом опускается, а порядок равен нолю. Знак порядка опускается только, если порядок равен нолю. Знак числа опускается, только если оно равно нолю. Разделитель мантиссы и порядка – буква "E" верхнего регистра. Разделитель целой и дробной части мантиссы – точка.
.

Добавлено через 4 минуты
Цитата Сообщение от iifat Посмотреть сообщение
Ну обязана ж она быть!
А вот фиг. Нету. Забыл.
В нормальных языках оператора степени не бывает. Это связано с тем, что для отрицательных чисел действительная степень не определена.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
05.01.2013, 19:12     Парсинг и валидация записи числа #30
Цитата Сообщение от taras atavin Посмотреть сообщение
В нормальных языках оператора степени не бывает. Это связано с тем, что для отрицательных чисел действительная степень не определена.
Если уж так категорично, то нормальные языки поддерживают множество комплексных чисел в том числе.
iifat
2179 / 1332 / 96
Регистрация: 05.06.2011
Сообщений: 3,692
05.01.2013, 19:34     Парсинг и валидация записи числа #31
Цитата Сообщение от taras atavin Посмотреть сообщение
В нормальных языках оператора степени не бывает. Это связано с тем, что для отрицательных чисел действительная степень не определена.
Нууу, тогда б в них и деления не было б -- на нуль-то делить нельзя! Впрочем, не суть, конечно, что это мы вообще в форуме ++ про нормальные языки заговорили Забанят же ж!
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
05.01.2013, 20:31  [ТС]     Парсинг и валидация записи числа #32
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Если уж так категорично, то нормальные языки поддерживают множество комплексных чисел в том числе.
http://www.cyberforum.ru/cgi-bin/latex.cgi?-27^{\frac{1}{3}}=\sqrt[3]{-27}=-3 и http://www.cyberforum.ru/cgi-bin/latex.cgi?-27^{\frac{1}{3}}=\left( -27^2\right)^{\frac{1}{6}}=729^{\frac{1}{6}}=\sqrt[6]{729}=3. Какое из значений истинно? Заметь, корня из минус единицы нет ни в одном из двух.

Добавлено через 13 минут
Цитата Сообщение от iifat Посмотреть сообщение
Нууу, тогда б в них и деления не было б -- на нуль-то делить нельзя! Впрочем, не суть, конечно, что это мы вообще в форуме ++ про нормальные языки заговорили Забанят же ж!
Деление на ноль вызывает исключение, а отрицательные числа во-первых можно возводить в степень с целым показателем, а во-вторых можно определить какое нибудь не стандартное соответствие степени корню, а корни то отрицательных чисел определены. В области положительных чисел все степени корней эквивалентны просто корню, а для отрицательных имеем неоднозначность, которую можно разрулить соглашением, для каждого соглашения можно написать свою функцию.

Добавлено через 1 минуту
И иметь таких функция несколько для одних и тех же типов.

Добавлено через 26 минут
Или так: http://www.cyberforum.ru/cgi-bin/latex.cgi?x^{a}=e^{a*ln(x)}, http://www.cyberforum.ru/cgi-bin/latex.cgi?e^{ln(x)}=x, выполним замену: http://www.cyberforum.ru/cgi-bin/latex.cgi?y=(-1)*x, тогда http://www.cyberforum.ru/cgi-bin/latex.cgi?x=(-1)*y http://www.cyberforum.ru/cgi-bin/latex.cgi?ln((-1)*y)=ln(-1)+ln(y), а так как http://www.cyberforum.ru/cgi-bin/latex.cgi?e^{\pi i+2\pi n}=-1, то http://www.cyberforum.ru/cgi-bin/latex.cgi?ln(-1)=\pi i+2\pi n, выбираем одно значение по вкусу, но опять соглашение.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
05.01.2013, 21:21     Парсинг и валидация записи числа #33
А что не так? –271/3 = e(Ln –27)/3. Ln –27 = ln 27 + i(π + 2πk). –271/3 = 9ei(π + 2πk)/3, k ∈ ℤ. Комплексный логарифм многозначен. Все значения истинны. И по идее результатом должны быть именно все они. (Ну или главное значение при k = 0, то есть 9i2/3. Точнее, три главных значения, лол.)
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
05.01.2013, 21:24  [ТС]     Парсинг и валидация записи числа #34
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
И по идее результатом должны быть именно все они.
Результатов операции не может быть бесконечно много, это неоднозначность, но здесь то её можно разрулить соглашением, а к нему написать функцию. Кроме того, http://www.cyberforum.ru/cgi-bin/latex.cgi?{-27}^{\frac{1}{3}}=\sqrt[3]{-27}=-3, то есть имеет действительное значение, которое тоже можно прописать по какому нибудь соглашению.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
05.01.2013, 21:26     Парсинг и валидация записи числа #35
С чего вы взяли? Только потому, что это не очень удобно реализовывать?

Если серьёзно, то я что-то не вижу проблем. Частичные функции в виде элементарных операторов есть — то же деление. С вычитанием беззнаковых величин тоже как-то разрулили. С действительными корнями из отрицательных величин тоже. Так что аргумент "эта функция не везде (однозначно) определена" против оператора возведения в степень слабоват. Ведь можно заставить FPU бросаться исключением наконец.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.01.2013, 21:33     Парсинг и валидация записи числа
Еще ссылки по теме:

C++ Парсинг файлов, найти целые числа
C++ Проверить, есть ли в записи числа m цифры, совпадающие с цифрами в записи числа n
Даны натуральные числа n, k. Проверить, есть ли в записи числа n (в степени k) цифра m C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
05.01.2013, 21:33  [ТС]     Парсинг и валидация записи числа #36
А деление на 0 - это просто запрещённая операция, по которой вылетает только исключение. Поэтому степень может быть только функцией, а к делению это не относится.

Добавлено через 4 минуты
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Если серьёзно, то я что-то не вижу проблем. Частичные функции в виде элементарных операторов есть — то же деление. С вычитанием беззнаковых величин тоже как-то разрулили. С действительными корнями из отрицательных величин тоже. Так что аргумент "эта функция не везде (однозначно) определена" против оператора возведения в степень слабоват. Ведь можно заставить FPU бросаться исключением наконец.
А потом придёшь ты и пожелаешь определить действительную степень отрицательного числа через комплексный логарифм, выбрав значение при n=0, сохранив при этом версию с теми же типами операндов, бросающую исключение. Проблема не в том, что бывают исключения, а в том, что в определённой области значений операндов существует простор для соглашений, а количество операторов ограничено. Определять функцию степени ни кто не запрещал.
Yandex
Объявления
05.01.2013, 21:33     Парсинг и валидация записи числа
Ответ Создать тему
Опции темы

Текущее время: 06:07. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru