Я только начинаю изучать блок в своем классе информатики, и у меня есть присвоение на раунд значение с плавающей точкой с помощью указанного режима округления. Я попытался реализовать это использование fstcw
, fldcw
, и frndint
. Я изменяю округляющиеся биты управления, вокруг числа, и затем восстанавливаю предыдущие биты управления (требование присвоения).
Текущая нерешенная проблема состоит в том что инструкция fld %1
кажется, загружает неправильное значение в st(0)
регистр с плавающей точкой (например, если я вызываю функцию со значением 2,6207, номер-1.9427 (...) электронный 29, загружается в регистр). Это может произойти из-за неправильного употребления gcc
встроенный asm()
, или что-то еще, но я не уверен, почему это происходит.
Вот то, что я имею:
double roundD (double n, RoundingMode roundingMode)
{
// control word storage (2 bytes for previous, 2 for current)
char *cw = malloc(4*sizeof(char));
char *cw2 = cw + 2;
asm("fstcw %3;" // store control word in cw
"mov %3,%4;" // copy control word into cw2
"and $0xF3FF,%4;" // zero out rounding control bits
"or %2,%4;" // put new mode into rounding control bits
"fldcw %5;" // load the modified control word
"fld %1;" // load n into st(0)
"frndint;" // round n
"fstp %0;" // load st(0) back into n
"fldcw %3;" // load the old control word from cw
: "=m" (n)
: "m" (n), "m" (roundingMode),
"m" (cw), "r" (cw2), "m" (cw2) // mov requires one argument in a register
);
free(cw);
return n;
}
Я ценил бы любые указатели на что случилось с тем кодом, конкретно касающимся fld %1
строка и asm
исходные данные/выводы. (Конечно, если можно найти другие проблемы, не стесняйтесь сообщать мне о них также.) Я не хочу, чтобы любой сделал мою домашнюю работу для меня, просто указал на меня в правильном направлении.Спасибо!
По крайней мере, одна проблема с вашим текущим кодом заключается в том, что он использует версии fld и fstp с плавающей запятой одинарной точности. Если вы замените их на fldl и fstpl, возможно, это сработает.
Если вы используете ветвь с именем heroku в качестве «альтернативной главной» ветви (с конфиденциальными данными) и старую главную ветвь без конфиденциальных данных, то вы всегда можете сделать
git merge master
Так что вы можете толкать ветвь heroku в heroku не главную ветвь.
-121--2414480-У меня нет алгоритма, чтобы дать вам ключевые функции, но вот некоторые вещи, которые могут помочь.
Во-первых, я бы не стал слишком беспокоиться о поиске характерного пикселя для каждого символа, потому что, в среднем, проверка соответствия данного символа заданному образу (5x5) двоичного изображения не должна занимать больше 5-7 проверок, чтобы сказать, что нет совпадения. Почему? Вероятность. Для 7 двоичных пикселей существует 2 * * 7 = 128 различных возможностей. Это означает, что вероятность совпадения символа до 7 пикселей составляет 1/128 < 1%. Просто убедитесь, что вы остановите сравнения, когда обнаружите несоответствие.
Во-вторых, если вы не хотите делать хэш-таблицу, вы можете использовать trie для хранения всех ваших символьных данных. Он будет использовать меньше памяти, и вы будете проверять все символы одновременно. Поиск не будет таким быстрым, как в хэш-таблице, но также не придется преобразовывать в последовательность. В каждом узле дерева может быть не более 2 потомков. Например, если у вас есть два символа 2x2 (назовем их A и B):
A B
01 00
10 11
У вас будет только один потомок в первом узле - только слева (ветвь 0). Переходим к следующему узлу. Он имеет два потомка, левая (0) ветвь ведёт к остальной части B, а правая (1) ветвь ведёт к остальной части A. Вы получаете картину. Дайте мне знать, если эта часть не ясна.
-121--3653456-Изменение знака означает, что бит знака (который является наиболее значимым, первым) неверен. Это означает, что указатель% 1 неправильно выровнен. Если у вас есть один байт, он может начать с 0,1,2... но если вы получаете доступ к двум байтам, адрес должен быть 0,2,4.... и в случае double адрес должен быть четным разделяемым на 8: 0,8,16
Поэтому проверьте, является ли адрес, который используется для загрузки значения, разделяемым на 8. Сборка имеет ключевое слово align, гарантирующее правильное выравнивание данных.
Вот что у меня есть. Он не тестировался, но, надеюсь, вам будет проще работать с ним. : -)
double
roundd(double n, short mode)
{
short cw, newcw;
__asm__("fstcw %w0" : "=m" (cw));
newcw = cw & 0xf3ff | mode;
__asm__("fldcw %w0" : : "m" (newcw));
__asm__("frndint" : "+t" (n));
__asm__("fldcw %w0" : : "m" (cw));
return n;
}
Хотя, если вам не требуется использовать сборку для достижения вашего режима округления, подумайте об использовании вместо этого функций из
. : -)