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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
#1

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

04.01.2013, 10:16. Просмотров 1212. Ответов 35
Метки нет (Все метки)

Дана запись числа:
Все дробные числа пишутся в знаковом десятичном формате с плавающей запятой со знаковым порядком. Знак + числа в целом опускается. Если число равно нолю, то: знак числа в целом опускается, а порядок равен нолю. Знак порядка опускается только, если порядок равен нолю. Разделитель мантиссы и порядка – буква "E" верхнего регистра. Разделитель целой и дробной части мантиссы – точка.
, требуется выполнить её валидацию и вернуть double в значении функции и код ошибки через параметр. Как нибудь я это распарсю, вопрос в том, как сделать лучше и как сделать валидацию.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.01.2013, 10:16
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Парсинг и валидация записи числа (C++):

валидация числа - C++
как сделать валидацию такого числа 10000000.89 ? что бы было всегда 8 чисел до запятой и 2 после

Есть в записи числа m цифры, которые совпадают с цифрами в записи числа n - C++
Дано два натуральных числа n(<=9999) и m (<=9999). Проверить, есть в записи числа m цифры, которые совпадают с цифрами в записи числа n. ...

Проверить, есть ли в записи числа m цифры, совпадающие с цифрами в записи числа n - C++
Помогите составить программу. Условие: Даны два натуральных числа m и n{m< 9999, n < 9999). Проверить, есть ли в записи числа m...

Парсинг файла игнорирует числа - C++
Всем добрый день. Пытаюсь прочитать данные из файла 3D модели в формате OBJ. bool L_ObjData::LoadFromFile(string FileName) { ...

Парсинг файлов, найти целые числа - C++
добрый день, требуется следующее: есть файл list.txt его содержимое каждая строчка содержит путь к файлу например D:\file1.txt...

Даны натуральные числа n, k. Проверить, есть ли в записи числа n (в степени k) цифра m - C++
За основу вот взял этот код: #include<iostream> #include <vector> using namespace std; int main() { vector<long long>...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
iifat
2232 / 1385 / 103
Регистрация: 05.06.2011
Сообщений: 3,811
04.01.2013, 18:35 #16
Цитата Сообщение от taras atavin Посмотреть сообщение
Тогда исходные данные не валидны
Не вопрос. Прога-то твоя вылетит! А не должна. Об том и валидация.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
04.01.2013, 18:45  [ТС] #17
А как?
iifat
2232 / 1385 / 103
Регистрация: 05.06.2011
Сообщений: 3,811
04.01.2013, 19:17 #18
Ну, как -- как обычно. Например, как я набросал чуть выше -- эта не вылетает. А вообще -- ну просто иметь в виду, что всё может быть неправильно.
В числе обязана быть точка, но может отсутствовать. Значит, надо учесть этот момент. Как? Ну, например, присваиваем p перед циклом -1, а после проверяем, что >=0, иначе выдаём код.
Да, кстати, тебе ж тут советовали грамматики и регулярные выражения. В принципе, конечно, правильно, только это полгода разбираться будешь. Если в перспективе кие-нибудь сложные парсеры -- имеет смысл, а для конкретной задачи -- имхо, нет.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
05.01.2013, 13:43  [ТС] #19
Цитата Сообщение от iifat Посмотреть сообщение
Например, как я набросал чуть выше -- эта не вылетает.
А как именно реагирует?

Добавлено через 7 минут
Цитата Сообщение от iifat Посмотреть сообщение
const char *const Buffer,
А мне надо str::string.
Цитата Сообщение от iifat Посмотреть сообщение
if (*p=='.') {char *p0 = ++p; int after_p = sliceInt (p); Result += after_p * 0.1 ^ (p-p0);}
* if (*p=='E') {++p; int exp_p = sliceInt (p); Result *= 10 ^ exp_p;}
* if (*p) {error} // неведомые символы в конце строки
А где цикл?

Добавлено через 14 минут
Цитата Сообщение от iifat Посмотреть сообщение
Result = sliceInt (p);
И как это решит проблему? Если уж нельзя выдать сообщение, то пусть лучше вылетает. Гарантия того, что функция не проглотит нечто, не соответствующее фрагменту спецификации формата, относящемуся к именно её части файла, обязательна, код ошибки желателен, причём, без подробностей, просто TPXSMRParseError. В особо запущенных случаях пусть падает, лишь бы только не пропустить что нибудь "левое".

Добавлено через 16 минут
Проблема в том, что целые и действительные в разных системах счисления: целые шестандцатеричные, но без ведущих символов 0x, а действительные десятичные. И если вдруг должно быть действительное, а ни точки, ни E в нём не окажется, то вообще не понятно, "200" - это сколько: 200, или 512 и сколько в этой записи числа вообще ошибок.

Добавлено через 3 минуты
Цитата Сообщение от iifat Посмотреть сообщение
Да, кстати, тебе ж тут советовали грамматики и регулярные выражения. В принципе, конечно, правильно, только это полгода разбираться будешь. Если в перспективе кие-нибудь сложные парсеры -- имеет смысл, а для конкретной задачи -- имхо, нет.
Это и есть часть более сложного парсера.
iifat
2232 / 1385 / 103
Регистрация: 05.06.2011
Сообщений: 3,811
05.01.2013, 13:55 #20
Цитата Сообщение от taras atavin Посмотреть сообщение
А как именно реагирует?
Просто закончит разбор. А потом увидит, что разобрана не вся строка и выдаст ошибку.
C++
1
if (*p) {error} // неведомые символы в конце строки
-- я просто коркретику не стал прописывать.
Цитата Сообщение от taras atavin Посмотреть сообщение
А мне надо str::string
Прикинь, как переписать на std::string. Я из изучать пока не рвусь.
Цитата Сообщение от taras atavin Посмотреть сообщение
А где цикл?
В sliceInt -- она там тоже есть.
Цитата Сообщение от taras atavin Посмотреть сообщение
Если уж нельзя выдать сообщение, то пусть лучше вылетает
Что значит -- нельзя? Можно, и не одним способом, и совершенно различной подробности. Один из способов я тебе даже набросал. Не самый лучший, разумеется -- лучшие гораздо сложнее.
Цитата Сообщение от 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
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
05.01.2013, 14:13  [ТС] #22
Во вложении полная спецификация, глотать не валидное нельзя категорически, выдача кода ошибки только желательна, подробности не требуются, в первом посте подзадача в задаче парсинга всего файла.
Вложения
Тип файла: rar Формат xsm версии 00000000.rar (4.5 Кб, 3 просмотров)
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
2232 / 1385 / 103
Регистрация: 05.06.2011
Сообщений: 3,811
05.01.2013, 16:02 #24
Цитата Сообщение от taras atavin Посмотреть сообщение
Зачем ксорить разность с константой?
Хотел написать возведение в степень. Забыл, как оно в Цэ пишется.

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

Добавлено через 7 минут
С 105 строки кая-то ересь пошла. Ты ж умеешь читать целое число (строки 82-93). Повтори, если уж так не любишь выделять подпрограммы. И, кстати, похоже, порядок (после E) у тебя сначала er, а с 122 -- re. Ну и, напоследок, для умножения на 10 в степени ха есть гораздо более приятные методы, чем цикл от 1 до ха.
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
~ Эврика! ~
1243 / 992 / 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
Ушёл с форума.
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
2232 / 1385 / 103
Регистрация: 05.06.2011
Сообщений: 3,811
05.01.2013, 18:24 #28
Цитата Сообщение от taras atavin Посмотреть сообщение
В чём ересь?
Ну, сравни же в 82-й! Result ты начинаешь с нуля -- почему re = 1? И где de *= 10?
Цитата Сообщение от 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
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
05.01.2013, 19:12 #30
Цитата Сообщение от taras atavin Посмотреть сообщение
В нормальных языках оператора степени не бывает. Это связано с тем, что для отрицательных чисел действительная степень не определена.
Если уж так категорично, то нормальные языки поддерживают множество комплексных чисел в том числе.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.01.2013, 19:12
Привет! Вот еще темы с ответами:

Даны натуральные числа n, k. Проверить, есть ли в записи числа nk цифра m - C++
Помогите пожалуйста:Даны натуральные числа n, k. Проверить, есть ли в записи числа nk цифра m

Для натурального числа определить истинность предиката «все цифры в записи числа равны» - C++
Для натурального числа определить истинность предиката «все цифры в записи числа равны». Если предикат истинен, то вывести эту цифру.

Задано два натуральных числа: m и n. Определить, сколько цифр содержится в десятичной записи числа m^n. - C++

Составить программу,которая для любого натурального числа печатает количество цифр в записи этого числа - C++
Помагите решить такую штукенцию=) Составить программу,которая для любого натурального числа печатает количество цифр в записи этого...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
05.01.2013, 19:12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru