Проверка на число
Необходимо проверить строку, т.е. является ли она числом или нет, причем число может быть большим, порядка 13 знаков.
Поэтому вот такой вариант не проходит:
{
int i;
i = StrToInt(Строка);
}
catch (EConvertError&)
{
// ошибка конвертации
;
}
Может есть какая-нить стандартная функция?
Добрый день!
Необходимо проверить строку, т.е. является ли она числом или нет, причем число может быть большим, порядка 13 знаков.
Поэтому вот такой вариант не проходит:
{
int i;
i = StrToInt(Строка);
}
catch (EConvertError&)
{
// ошибка конвертации
;
}
Может есть какая-нить стандартная функция?
Функция isdigit.
Header File
ctype.h, mbstring.h
Category
Classification Routines
Prototype
int isdigit(int c);
int iswdigit(wint_t c);
int _ismbcdigit(unsigned int c);
Description
Tests for decimal-digit character.
isdigit is a macro that classifies ASCII-coded integer values by table lookup. The macro is affected by the current locale’s LC_CTYPE category. For the default C locale, c is a digit (0 to 9).
You can make this macro available as a function by undefining (#undef) it.
Return Value
isdigit returns nonzero if c is a digit.
_ismbcdigit returns true if and only if the argument c is a single-byte representation of an ASCII digit.
Может есть какая-нить стандартная функция?
Можно написать свою нестандартную очень быстро, если стандартную не найдешь:
{
for(int i = 0; i < S.Length(); i++)
if(S < '0' || S > '9')
return false;
return true;
}
не помню только с 0 или с 1 в билдере символы в String нумеруются. Код неоптимальный, вероятно если бежать по строке не используя оператор [], а при помощи указателей то быстрее получится (а может и нет - не проверял)
Можно написать свою нестандартную очень быстро, если стандартную не найдешь:
{
for(int i = 0; i < S.Length(); i++)
if(S < '0' || S > '9')
return false;
return true;
}
не помню только с 0 или с 1 в билдере символы в String нумеруются. Код неоптимальный, вероятно если бежать по строке не используя оператор [], а при помощи указателей то быстрее получится (а может и нет - не проверял)
Еще нужно добавить проверочку на "+","-","." или ","
Еще нужно добавить проверочку на "+","-","." или ","
Ну надо, так надо. Это не сложно :)
for (int i = strlen(p) - 1; i >= 0; i--)
if (!isdigit(p))
;
в функцию это дело запихивать не очень целесообразно, т.к. массив данных большой.
да я уж до этого дошел, вот по-моему самый оптимальный:
for (int i = strlen(p) - 1; i >= 0; i--)
if (!isdigit(p))
;
в функцию это дело запихивать не очень целесообразно, т.к. массив данных большой.
Может и так, только непонятно сразу быстрее ли будет вызывать функцию isdigit для каждого символа, или просто проверять не равен ли этот символ одному из набора - ведь их не так уж и много, цифры, да несколько знаков.
А какое значение имеет длина массива для вызова функции - передается все равно только указатель независимо от длины.
А какое значение имеет длина массива для вызова функции - передается все равно только указатель независимо от длины.
под понятием "массив" я имел ввиду не форму организации данных в языке программирования, а некоторую совокупность данных, в моем случае это файл, в котором порядка 35 тыщ. строк, каждую из которых необходимо проверить на число, а если каждый раз при проверки строки вызывать функцию, то на этот вызов буду терять время, зачем?
под понятием "массив" я имел ввиду не форму организации данных в языке программирования, а некоторую совокупность данных, в моем случае это файл, в котором порядка 35 тыщ. строк, каждую из которых необходимо проверить на число, а если каждый раз при проверки строки вызывать функцию, то на этот вызов буду терять время, зачем?
Согласен, только тогда тем более нет смысла вызывать функцию (isdigit) для каждого символа, ведь из гораздо больше чем 35 тысяч.
Можно написать свою нестандартную очень быстро, если стандартную не найдешь:
{
for(int i = 0; i < S.Length(); i++)
if(S < '0' || S > '9')
return false;
return true;
}
не помню только с 0 или с 1 в билдере символы в String нумеруются. Код неоптимальный, вероятно если бежать по строке не используя оператор [], а при помощи указателей то быстрее получится (а может и нет - не проверял)
не работает этот код, ошибку искать не стал, а сделать нужно вот так:
{
for (int i = strlen(S) - 1; i >= 0; i--)
if(S < '0' || S > '9')
return false;
return true;
}
Добрый день!
Необходимо проверить строку, т.е. является ли она числом или нет, причем число может быть большим, порядка 13 знаков.
Поэтому вот такой вариант не проходит:
{
int i;
i = StrToInt(Строка);
}
catch (EConvertError&)
{
// ошибка конвертации
;
}
Может есть какая-нить стандартная функция?
А такой вариант не пойдёт?
{
double i;
i = StrToFloat(Строка);
}
catch (EConvertError&)
{
// ошибка конвертации
;
}
Кстати очень не советую и спользовать исключения в качетве определения чего-то там. Их всегда надо использовать на крайний случай.
1) Обоснуй. И поясни, что такое "крайний случай".
2) Скажи это создателям StrToFloat - другого способа сообщить о неудаче преобразования строки в число, кроме выбрасывания исключения, у этой функции нет.
А и использовать я их не люблю потому что они не объясняют в какой строчке произошла ошибка, но и ставить на каждую команду отдельное исключение тоже на мой взгяд неверно.
Может просто я их не умею правильно использовать. Но практика показала, что лучше обходится без них.
Исключения изначально были созданы, только для обработки случаев не подчиняющихся стандартной логике.
Всмысле их надо использовать когда без них не обойтись.
А и использовать я их не люблю потому что они не объясняют в какой строчке произошла ошибка, но и ставить на каждую команду отдельное исключение тоже на мой взгяд неверно.
Но практика показала, что лучше обходится без них.
Исключения изначально были созданы, только для обработки случаев не подчиняющихся стандартной логике.
Чепуху говоришь.
Может просто я их не умею правильно использовать.
А вот это весьма вероятно :)
Исключения изначально были созданы, только для обработки случаев не подчиняющихся стандартной логике.
Серьёзно тебе говорю))
Например деление на нуль или выход за пределы памяти.
Где-то читал.
Серьёзно тебе говорю))
Например деление на нуль или выход за пределы памяти.
Где-то читал.
Ну-ну. Информационно агентство "ОБСДП" - Одна Баба Сказала, Другая Повторила :)
Цитирую по книге Бьерна Страуструпа "Язык программирования С++. Третье издание" ("Невский Диалект", "Издательство БИНОМ", 1999г.):
[FONT=times new roman][COLOR=purple][SIZE=3]Фундаментальная идея состоит в том, что функция, обнаружившая проблему, но не знающая как её решить, генерирует (throw) исключение в надежде, что вызвавшая её (непосредственно или косвенно) функция сможет решить возникшую проблему. Функция, которая хочет решать проблемы данного типа, может указать, что она перехватывает (catch) такие исключения.[/SIZE][/COLOR][/FONT]
И оттуда же:
[FONT=times new roman][COLOR=purple][SIZE=3]Механизм обработки исключений предоставляет альтернативу традиционным методав в тех случаях, когда они недостаточны, не элегантны и подвержены ошибкам. Он предоставляет способ явного отделения кода обработки ошибки от "обычного" кода, делая таким образом программу более читабельной и лучше подходящей для различных инструментальных средств. Механизм обработки исключений предоставляет более регулярный способ обработки ошибок, упрощая в результате взаимодействие между отдельно написанными фрагментами кода.[/SIZE][/COLOR][/FONT]
А и использовать я их не люблю потому что они не объясняют в какой строчке произошла ошибка, но и ставить на каждую команду отдельное исключение тоже на мой взгяд неверно.
Ты действительно не умеешь их готовить.
Простейший вариант:
throw "pointer == 0 in line 24";
Обычно это оборачивается в макрос:
#define LINE_STR(x) LINE_STR2(x)
#define ASSERT(exp) if(!(exp)) throw #exp" in line " LINE_STR(__LINE__)
А кто тебе объясняет в какой строчке произошла ошибка без использования исключений?
А такой вариант не пойдёт?
{
double i;
i = StrToFloat(Строка);
}
catch (EConvertError&)
{
// ошибка конвертации
;
}
Если внимательно читать обсуждение то видно, что автор начал именно с этого варианта и он ему не подошел. Насколько я понял важна скорость работы. Посмотрим с этой позиции:
1. StrToFloat кроме проверки на валидность осуществляет перевод в плавающее. Быстрее ли это чем просто проверка на валидность? Далеко не уверен.
2. Генерация исключения занимает тоже достаточно много времени и работает медленне, чем if ... then.
Следовательно приобретая в минимальности написания кода мы теряем в производительности. Так что думаю код
{
for(int i = 0; i < S.Length(); i++)
if(S < '0' || S > '9')
return false;
return true;
}
по любому будет работать быстрее.
Если внимательно читать обсуждение то видно, что автор начал именно с этого варианта и он ему не подошел. Насколько я понял важна скорость работы. Посмотрим с этой позиции:
1. StrToFloat кроме проверки на валидность осуществляет перевод в плавающее. Быстрее ли это чем просто проверка на валидность? Далеко не уверен.
2. Генерация исключения занимает тоже достаточно много времени и работает медленне, чем if ... then.
Следовательно приобретая в минимальности написания кода мы теряем в производительности. Так что думаю код
{
for(int i = 0; i < S.Length(); i++)
if(S < '0' || S > '9')
return false;
return true;
}
по любому будет работать быстрее.
Если внимательно читать обсуждение, то видно, что автор начал вовсе не с этого варианта, а с варианта StrToInt. Чувствуете разницу?
Почему ему не подошёл StrToInt? Да потому что строка у него длинная, содержит "порядка 13 знаков". Нетрудно убедиться, что такое большое число в границы диапазона int не уместится, и произойдёт сбой, даже если строка и содержит одни цифры.
И с чего вы взяли, что надёжность и удобочитаемость отлаженной библиотечной функции и стандартного языкового механизма стоят мифического выигрыша в производительности? Что выигрыш мифический, нетрудно убедиться, слегка пораскинув мозгами. Самый медленный элемент программы - это прокладка между стулом и клавиатурой. Юзер не заметит даже 10-миллисекундной разницы в выполнении двух операций. Ладно бы эта проверка выполнялась непрерывно в цикле 10000000 раз, а так...
Если внимательно читать обсуждение, то видно, что автор начал вовсе не с этого варианта, а с варианта StrToInt. Чувствуете разницу?
Почему ему не подошёл StrToInt? Да потому что строка у него длинная, содержит "порядка 13 знаков". Нетрудно убедиться, что такое большое число в границы диапазона int не уместится, и произойдёт сбой, даже если строка и содержит одни цифры.
И с чего вы взяли, что надёжность и удобочитаемость отлаженной библиотечной функции и стандартного языкового механизма стоят мифического выигрыша в производительности? Что выигрыш мифический, нетрудно убедиться, слегка пораскинув мозгами. Самый медленный элемент программы - это прокладка между стулом и клавиатурой. Юзер не заметит даже 10-миллисекундной разницы в выполнении двух операций. Ладно бы эта проверка выполнялась непрерывно в цикле 10000000 раз, а так...
Взял я вот с чего:
1.
в моем случае это файл, в котором порядка 35 тыщ. строк, каждую из которых необходимо проверить на число
. Т.е. эта проверка выполняется в цикле и по крайней мере 35000 раз. Так что, какой бы Олвейз не лежал между стулом и клавой это уже существенно.
2. Ваша удобочитаемая, стандартная, библиотечная функция предназначена совсем не для проверки на валидность строки, а для перевода ее в число. Т.е. вы сами, заведомо , порождаете ошибочную ситуацию и делаете массу не нужного, только из - за того, что влом подумать и написать 4 оператора. Эта функция,в смысле понятности программы, только запутывает ситуацию и следовательно не дает преимущества даже в ясности и прозрачности алгоритма.
3. Далеко не все программы и не всегда имеют интерфейс с пользователем.
4. Исскуство программирования и состоит в том, чтобы в каждый момент проектирования и написания программы искать и находить оптимальные решения. Только тогда Ваш проект будет действительно успешным.
Взял я вот с чего:
1. . Т.е. эта проверка выполняется в цикле и по крайней мере 35000 раз. Так что, какой бы Олвейз не лежал между стулом и клавой это уже существенно.
2. Ваша удобочитаемая, стандартная, библиотечная функция предназначена совсем не для проверки на валидность строки, а для перевода ее в число. Т.е. вы сами, заведомо , порождаете ошибочную ситуацию и делаете массу не нужного, только из - за того, что влом подумать и написать 4 оператора.
3. Далеко не все программы и не всегда имеют интерфейс с пользователем.
4. Исскуство программирования и состоит в том, чтобы в каждый момент проектирования и написания программы искать и находить оптимальные решения. Только тогда Ваш проект будет действительно успешным.
полностью согласен. :D
вот тот способ с исключением я не сам придумал, просто мне его предложили, а я уже начал искать стандартную функцию, т.к. писать код, который будет работать на исключении не совсем правильно, сугубо мое мнение.
1. Т.е. эта проверка выполняется в цикле и по крайней мере 35000 раз. Так что, какой бы Олвейз не лежал между стулом и клавой это уже существенно.
2. Ваша удобочитаемая, стандартная, библиотечная функция предназначена совсем не для проверки на валидность строки, а для перевода ее в число. Т.е. вы сами, заведомо , порождаете ошибочную ситуацию и делаете массу не нужного, только из - за того, что влом подумать и написать 4 оператора.
3. Далеко не все программы и не всегда имеют интерфейс с пользователем.
4. Исскуство программирования и состоит в том, чтобы в каждый момент проектирования и написания программы искать и находить оптимальные решения. Только тогда Ваш проект будет действительно успешным.
Использовать исключения для реализации ветвления стандартного алгоритма - плохая идея.
Исключения стоит использовать там, где действительно идет отклонение от нормального выполнения.
Например, отсутствие файла при его парсинге - это исключение.
Но отсутствие файла при проверке его наличия на диске - это не исключение, а вариант нормального алгоритма, т.е. просто ветвление.
Т.о. если задачей автора топика было бы перевод строки в число - то исключение здесь уместно. Но если автор пытается проверить можно ли провести такое преобразование, то исключение уже неуместно. Поэтому с пунктом 2 я согласен.
С пунктом 4 несогласен:
1) оптимальные решения нужно искать в процессе оптимизации, а не "в каждый момент проектирования и написания программы";
2) оптимальность имеет критерии и невсегда эти критерии - это скорость.
С пунктом 4 несогласен:
1) оптимальные решения нужно искать в процессе оптимизации, а не "в каждый момент проектирования и написания программы";
Вот здесь я не согласен. Есть, на мой взгляд очень хорошее правило: "Если хочется оптимизировать, не оптимизируй". Я понимаю его именно так, что не стоит оптимизацию выделять в отдельный процесс, а продумывать все на всех этапах производства программы. А уж ежели что-то хочется менять, то есть механизм версий.
2) оптимальность имеет критерии и невсегда эти критерии - это скорость.
Полностью согласен. Именно поэтому и употребил слово оптимальность, а не скорость.
Т.о. если задачей автора топика было бы перевод строки в число - то исключение здесь уместно. Но если автор пытается проверить можно ли провести такое преобразование, то исключение уже неуместно. Поэтому с пунктом 2 я согласен.
мне нужно было проверить является ли строка числом или нет т.е. там одни цифры в строке без пробелов и знаков препинания или нет, а как такового перевода нет.
Я понимаю его именно так, что не стоит оптимизацию выделять в отдельный процесс, а продумывать все на всех этапах производства программы.
Продумать все невозможно по определению, а в большинстве случаев совершенно бессмыслено.
Куда более продуктивный подход не "водопад", а итерационный.
Выделять же оптимизацию в отдельный процесс и можно и нужно.
Во-первых, как узнать, что именно оптимизировать?
Для этого существует предшествующий процесс - профайлинг.
Во-вторых, как понять, что оптимизация действительно осуществлена?
Для этого осуществляется повторный профайлинг.
Понятно, что профилировать надо уже существующую и работающую систему.
А уж ежели что-то хочется менять, то есть механизм версий.
Не совсем понял что имелось в виду... Итерационность? :)
Продумать все невозможно по определению, а в большинстве случаев совершенно бессмыслено.
Куда более продуктивный подход не "водопад", а итерационный.
Согласен. Еще Козьма Прутков говаривал:"Нельзя объять необъятное". Да и проектирование сверху вниз еще никто не отменял.
Выделять же оптимизацию в отдельный процесс, всетаки, по моему, на этой стадии не нужно.
Во-первых, как узнать, что именно оптимизировать?
Для этого существует предшествующий процесс - профайлинг.
Во-вторых, как понять, что оптимизация действительно осуществлена?
Для этого осуществляется повторный профайлинг.
Понятно, что профилировать надо уже существующую и работающую систему.
Я имел ввиду как раз стадию проектирвания и написания первой версии системы. Всетаки продумывать нужно по максимуму возможного. Чтобы в последствии оптимизировать как можно меньше. Это сокращает затраты.
Не совсем понял что имелось в виду... Итерационность? :)
Для начала оговорюсь, что все сказанное применимо не для всех и не всегда, но случается и довольно часто:
Имелось ввиду, что процесс оптимизации на стадии производства программного продукта, может приобрести лавинообразный, бесконечный, не управляемый характер, требующий все болшего и большего изменения текстов и даже концепций, заложенных в продукт. В результате не появляется даже первой версии. И вот тогда и приходит на помощь механизм версий. Зафиксировали 1-ую. Провели профайлинг, оптимизацию, дополнения и т.д. и получили 2-ую. Но надо понимать, что это уже другой программный продут. Ну и т.д. и т.п.
Поднимаю данный вопрос только в образовательных целях! :)
Вот такое решение мне тогда предложили:
{
double i;
i = StrToFloat(Строка);
}
catch (EConvertError&
{
// ошибка конвертации
;
}
вот что я нашел в справке Билдера:
TryStrToFloat
Converts a given string to a floating-point value with Boolean success code.
extern PACKAGE bool __fastcall TryStrToFloat(const AnsiString S, Extended &Value);
extern PACKAGE bool __fastcall TryStrToFloat(const AnsiString S, double &Value);
extern PACKAGE bool __fastcall TryStrToFloat(const AnsiString S, float &Value);
Description
Use TryStrToFloat to convert an AnsiString, S, to a floating-point value. S must consist of an optional sign (+ or -), a string of digits with an optional decimal point, and an optional mantissa. The mantissa consists of 'E' or 'e' followed by an optional sign (+ or -) and a whole number. Leading and trailing blanks are ignored.
The DecimalSeparator global variable defines the character that must be used as a decimal point. Thousand separators and currency symbols are not allowed in the string. If S doesn't contain a valid value, TryStrToFloat returns Default.
TryStrToFloat places the result in Value, and returns true if the conversion was successful, false otherwise.
из этого следует, что можно сделать вот так:
if (!TryStrToFloat(Строка, i))
// Не конвертируется
И не надо обрабатывать исключение.
Хочу узнать Ваше мнение господа.
Получается много работы...
и другие варианты...
Эх люди кто учил вас так писать?...
Вот:
bool isLongNum(char *s)
{
while ( *s ) // -- пока не конец строки (т.е. не 0)
{
d = *s - '0';
if (d > 9) return false;
s++;
}
return true;
}
А тебя то кто учил так писать?
Объявлять глобальные переменные, использовать неконстантный указатель в качестве аргумента?
Кроме того твой пример нерабочий при символах до '0', они у тебя тоже числа.
Кстати, а для чего вообще переменная (да ещё и глобальная) и операция вычитания?
Кроме того, в примере от _kolyan используется некоторый класс String, а не char*. Поэтому вполне возможно, что разындексирование - единственный или оптимальный путь обращения к символам.
Единственный недочет в его примере - передача объекта не по ссылке.
Вот моя модификация твоего примера:
{
while(*s>='0' && *s<='9') s++;
return (*s=='\0');
}
Здесь исправлена ошибка для символов меньше '0',
проведена оптимизация:
1) нет лишней переменной,
2) нет операции вычитания,
3) на типичной итерации всего две проверки, а не три.
и другие варианты...
Эх люди кто учил вас так писать?...
Вот:
bool isLongNum(char *s)
{
while ( *s ) // -- пока не конец строки (т.е. не 0)
{
d = *s - '0';
if (d > 9) return false;
s++;
}
return true;
}
Значение меньше 0 проверять не надо,
Но код, предложенный Green на много элегантнее
нефига он не элегантнее, по крайней меря не вижу в чем элегантность. может объяснишь ?
он использует возможности языка
не знаю поверишь ты или нет но мой код тоже использует возможности языка, но кроме того он еще решает задачу максимально эффективным способом а ваш вариант -- совсем не обязательно
:)
нет мы как раз не просто решаем задачи а пытаемся найти наилучшее решение для каждой задачи
+1
я бы рекомендовал как следует разобраться в коде прежде чем обвинять в его неработоспособности...
а насчет глобальных переменных -- мне так нравится, если не предполагается использовать ф-цию в многопоточных прилж-х -- это эффективнее
Ах да, не заметил unsigned...
Значит, у твоего кода ещё один минус - он интуитивно не ясен. зачем надо было заменять сравнение вычитанием? Для оптимизации? Но её нет, операции сравнения и вычитания соизмеримы по времени выполнения. Т.о. ты не избавился от сравнения, а сделал его неявным, чем усложнил читабельность кода. И того мы имеем на типичной итерации три операции, хотя можно ограничиться двумя, исключив из итерации проверку на конец строки. Ну и где же тут "максимальная эффективность"?
Что же касается глобальных переменных, то само их наличие - плохой тон, а уж использование там, где это совсем не требуется - совсем плохо. Хорошим стилем считается определять переменные непосредственно перед их использованием. Что же касается эффективности исполльзования глобальных переменных - так это туфта. Попробуй доказать обратное, кстати, указав критерий эффективности.
на остальные вопр. думаю ты сможешь ответить сам
Осталось непонятным, зачем нужна глобальная переменная и замена операции сравнения операцией вычитания. :)
да и кстати твоя модификация моего примера сводит на нет все преимущества моего примера )))
А они были? Какие?
да и еще встречный вопрос: почему для тебя принципиально передавать именно константный указатель ? ф-ция же не модифицирует строку...
Именно потому, что не модифицирует, надо передавать указатель на константу, иначе код не будет работать в таких случаях:
bool b = isLongNum(str);
по поводу оптимизации:
1. использование вычитания ==> у меня явным образом видно выполнение двух операций, у тебя их может быть три (а уж по числу пересылок между памятью и регистрами -- даже более существенная разница)
Ты что-то не в ту степь...
Смотри у тебя на типичной итерации:
while ( *s ) - раз операция (сравнение)
d = *s - '0'; - два операция (вычитание, про присвоение молчу)
if (d > 9) - три операция (сравнение)
В моём примере:
while(*s>='0' && *s<='9') - две операции сравнения (*s>='0' и *s<='9')
Третья проверка не включена в итерацию и поэтому выполняется всего один (!) раз.
Т.о. имеем для строки длинной n+1 (1 - это для учета завершающего нуля):
твой пример - 3n+1
мой пример - 2(n+1)+1
решаем неравенство: 3n+1 < 2(n+1)+1
и получаем, что лишь для n < 2 твой пример более эффективный, т.е. если мы хотим проверить строки типа "1", "2", "3" и т.д. Но для таких случаев можно предложить и более оптимальный алгоритм :)
В остальных же случиях (n>2) мой алгоритм оптимальнее.
2. глобальная переменная используется для экономии на стековых операциях, если не нравится можно сделать локальную статик-переменную
И как же она влияет на стековые операции :)
3. проверка на конец строки позволяет нам избавиться от использования strlen() -- сам понимаешь сколько операций это экономит,
Ты так и не понял. Можно обойтись без проверки на конец строки в итерации. Я же тебе показал как это сделать...
И strlen тут не при чем.
у вас там у кгого то еще был вариант с классом String и свойством.
У нас тут? А у тебя это где?
а на счет проверки на ноль -- так это операция проверки завершения цикла -- от нее ты никак не избавишься, я имею в виду что всегда есть некая проверка -- на ноль или не на ноль -- не важно; так что и у тебя такая поверка тоже есть, не сомневайся )))
Да я в курсе, что у меня она есть. Но ты понимаешь разницу между проверкой в цикле и за пределами цикла?
Объясняю: проверка в цикле будет выполняться столько раз, сколько будет итераций, проверка за пределами цикла будет выполняться один раз!
ты забыл про операцию && ))
Т.о. основа моего цикла -- 2 операции, основа твоего -- 3 вот и все
if(*s>='0') if(*s<='9') {} - это две операции,
а if(*s>='0' && *s<='9') {} - это уже три? :D
Так где ты увидел в моем цикле три операции?
А у тебя как раз три. Мне повторить какие?
Две проверки и одно вычитание.
-- хоть это уже и не относится к нашей задаче, но влияет так что их (стек-х оп-й) попросту нет ))
Стек есть всегда, а разница будет лишь в смещении. Вычесть 4 или вычесть 8 - это большая разница по производительности? :D
ну ка продемонстрируй еще раз, а то не хочется прокручивать все посты...
{
while(*s>='0' && *s<='9') s++; // в цикле проверки нет
return (*s=='\0'); // всегда одна(!) проверка за пределами цикла
}
как можно организовать цикл если проверка его завершения -- за пределами цикла?
М-да...
Ты пример мой смотрел?
Завершение цикла не обязательно должно быть жестко связано с концом строки.
ну а где ты у меня увидел три операции ?
Я в третий раз(!) повторяю:
while ( *s ) - раз операция (сравнение)
d = *s - '0'; - два операция (вычитание, про присвоение молчу)
if (d > 9) - три операция (сравнение)
не вижу ничего смешного и вобще хватит переходить на личности...
На личности? Личность это 4 или 8, или может улыбка в конце? :)
mov ax, [bp + N] -- есть вычисление адреса аргумента
mov ax, [addr] -- нету
есть разница ?
Ага, весомая разница... :)
Только так mov ax, [addr] не будет,
в обоих случаях будет mov ax, [bp + N]
Можешь проверить.
А вообще, неправильный подход закапываться с оптимизацией вглубь, когда ещё на поверхности есть чего оптимизировать.
while ((unsigned) (*s - '0') < 9) s++;
return *s == 0;
-- наиболее компактный код, не проигрывающий по производительности твоему,
а если строка длинная и удовлетворяет исходному условию (т.е. явл-ся числом), то и выигрывающий
[/code]
А чем этот код отличается от моего?
Тем что одну из операций сравнения заменил вычитанием?
Видимо, для запутывания верояного противника... :)
Выигрывающий у кого?
не будет если использ. глобальную переменную
А я говорю будет! :)
Докажи примером.
а я и не закапывался, я сразу привел более-менее оптимальный код а вы начали мудрить с strlen(), классом String и т д
Мы? Мы это кто?
Уже "более-менее оптимальный"? Раньше было "наиболее эффективный".
тем хотя бы что мой код сгенерирует меньше операций условного перехода
Угу... только на скорости это никак не отразится.
Кроме пограничных случаев, на них твой код проскальзывает, т.к. если *s < '0', то второя проверка не нужна, а в твоем случае все равно выполянятся обе операции. Но это мелочи.
а ты не понял ?
Нет не понял.
ладно уже начинается не обсуждение кода а выяснение отношений сворачиваем тему
Ок. :)