Мне кажется, что вы хотите построить (вручную) то, что составляет конечный автомат, где каждое состояние обрабатывает N-значную цифру или цифры экспонента; эта государственная машина будет иметь форму дерева (без петель!). Цель состоит в том, чтобы по возможности делать целочисленную арифметику и (очевидно) запоминать переменные состояния («ведущий минус», «десятичная точка в позиции 3») в состояниях неявно, чтобы избежать присвоений, хранилищ и более поздних выборок/тестов таких значений , Реализуйте машину состояний с обычными старыми операторами «if» только для входных символов (поэтому ваше дерево становится набором вложенных ifs). Встроенный доступ к символам буфера; вам не нужен вызов функции getchar
, чтобы замедлить работу.
Ведущие нули можно просто подавить; вам может понадобиться цикл, чтобы обрабатывать смехотворно длинные ведущие нулевые последовательности. Первая ненулевая цифра может быть собрана без обнуления аккумулятора или умножения на десять. Первые 4-9 отличных от нуля цифр (для 16-битных или 32-битовых целых чисел) могут быть собраны с целым умножением на постоянное значение десять (превращается большинством компиляторов в несколько смен и добавляет). [В верхней части: нулевые цифры не требуют никакой работы до тех пор, пока не будет найдена ненулевая цифра, а затем потребуется умножить 10^N на N последовательных нулей; вы можете подключить все это к машине состояния]. Цифры после первых 4-9 могут быть собраны с использованием 32 или 64 бит умножения в зависимости от размера слова вашего аппарата. Поскольку вы не заботитесь о точности, вы можете просто игнорировать цифры после того, как собрали 32 или 64 бита; Я бы предположил, что вы можете остановиться, когда у вас есть фиксированное количество ненулевых цифр, основанных на том, что ваше приложение действительно делает с этими числами. Десятичная точка, найденная в цифровой строке, просто вызывает ветвь в дереве конечных машин. Эта ветка знает неявное местоположение точки, и поэтому позже, как масштабировать с силой десять соответственно. С усилием вы можете комбинировать некоторые подэлементы конечного автомата, если вам не нравится размер этого кода.
[Над верхней частью: сохранить целые и дробные части в виде отдельных (малых) целых чисел. Это потребует дополнительной операции с плавающей запятой в конце, чтобы объединить целые и дробные части, возможно, не стоит].
[Сверху: соберите 2 символа для пар цифр в 16-битное значение, найдите 16-битное значение. Это позволяет избежать размножения в регистрах в торговле для доступа к памяти, возможно, не для победы на современных машинах].
При встрече с «E» собирайте экспоненту в виде целого числа, как указано выше; точно просмотрите предварительно вычисленную/масштабированную степень десяти в таблице предварительно вычисленного множителя (обратные, если знак «-» присутствует в экспоненте) и умножьте собранную мантиссу. (никогда не делайте разворота поплавка). Поскольку каждая процедура сбора экспонент находится в другой ветке (листе) дерева, она должна корректировать кажущееся или фактическое местоположение десятичной точки, компенсируя мощность десяти индексов.
[Наверху: вы можете избежать стоимости ptr++
, если знаете, что символы для номера хранятся линейно в буфере и не пересекают границу буфера. В k-м состоянии вдоль ветви дерева вы можете получить доступ к k-му символу как *(start+k)
. Хороший компилятор обычно может скрывать «... + k» в индексированном смещении в режиме адресации.]
Выполнено правильно, эта схема делает примерно одно дешевое многократное добавление на отличную от нуля цифру, одну букву с плавающей точкой мантиссы, а одно плавающее умножается на масштаб результата путем экспоненты и местоположения десятичной точки.
Я не реализовал вышеуказанное. Я реализовал ее версии с циклами, они довольно быстрые.
Проверяет изменения локали на `isdigit`? Возможно, они должны заглянуть в стандарт ISO C. `isdigit` не имеет локально-зависимого поведения; он должен проверить, является ли символ элементом от `0` до` 9`, и все. – Kaz 2015-03-30 15:02:24
Можете ли вы дать нам представление о проблемной области? Я предполагаю, что это не финансы, или вы будете использовать арифметику с фиксированной точкой. Это для системы управления, например позиционирования? У вас есть (жесткие или мягкие) требования в реальном времени? – 2015-08-27 22:09:45
Если вы можете изменить формат сообщения, очевидно, что отправка двоичных поплавков (или более простая текстовая кодировка двоичного файла) позволит сэкономить дорогостоящий синтаксический анализ на другом конце. например дамп float как целое шестнадцатеричное, если двоичный код не подходит, но это так. – 2016-01-22 13:49:28