Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.84.155] |
|
Страницы: (5) « Первая ... 3 4 [5] все ( Перейти к последнему сообщению ) |
Сообщ.
#61
,
|
|
|
Цитата Славян @ Разве Ява так делает? Да и не интерпретатор она.Их же тупой интерпретатор вполне способен скушать десятичное представление числа в записи строки pow(-32,-0.2) (или как у них там?) и выдать норм ответ!? Или ты про ЯваСкрипт? Там просто в операциях требующих числа, строки неявно преобразуются в числа. С вполне себе двоичным представлением. Аппаратно архитектура i86 поддерживает двоично-десятичное представление. Среди основных команд процессора есть команды двоично-десятичной коррекции при сложении/вычитании (байтовые, медленные, остались от i8086/88, в котором они были нужны для совместимости с i8080/85). И среди команд арифметического сопроцессора есть команды чтения/записи чисел в двоично-десятичном представлении - 19 двоично-десятичных цифр в десяти байтах. Но внутри процессора все числа оббрабатываются в двоичном виде. |
Сообщ.
#62
,
|
|
|
Да просто подумалось, что встретив явную запись pow( -32, -0.2) интерпретатор (или как он там?) вполне мог бы осознать, что можно по-грамотному посчитать, и выдал бы результат. Хотя, таких случаев мало, существенно чаще есть pow(-32, x), а ужо 'x' где-то выше берётся. И тут - да, затык, ибо перевелось всё в двоичный вид. Печалька.
Кстати, при разборе функции pow компилятор же мог бы умножать степень на нечётные числа и, в случае получения целого числа, мог бы сказать "ура! тут посчитается!" и посчитать. Или в этом направлении тоже есть изъян? Сходу пока не вижу. |
Сообщ.
#63
,
|
|
|
Цитата Славян @ при разборе функции pow компилятор же мог бы умножать степень на нечётные числа и, в случае получения целого числа, мог бы сказать "ура! тут посчитается!" и посчитать. Даже если ты напишешь (-1.0/7.0) он не поймет, для него 7.0 !== 7, и после попыток вычислить аргумент он получит опять двоичное число... |
Сообщ.
#64
,
|
|
|
Да, так прямо не вышло, но зато вот как вышло! :
#include <stdio.h> main() { double a=2.0/17; for( int i=3; i<100; i+=2) { double t = a*i - 2; printf("test %g",t); if( a*i!=double(2) ) printf(" %d:0\n",i); else printf(" %d:1!\n"); } printf("ok"); } test -1.64706 3:0 test -1.41176 5:0 test -1.17647 7:0 test -0.941176 9:0 test -0.705882 11:0 test -0.470588 13:0 test -0.235294 15:0 test -2.77556e-17 17:0 test 0.235294 19:0 test 0.470588 21:0 test 0.705882 23:0 test 0.941176 25:0 test 1.17647 27:0 test 1.41176 29:0 test 1.64706 31:0 test 1.88235 33:0 test 2.11765 35:0 test 2.35294 37:0 test 2.58824 39:0 test 2.82353 41:0 test 3.05882 43:0 test 3.29412 45:0 test 3.52941 47:0 test 3.76471 49:0 Добавлено Слегка изменил код и произошло угадывание! : double a=2.0/17; for( int i=3; i<100; i+=2) { double t = fmod(a*i,1); printf("\ntest %d: err=%g",i,t); if( t!=0 ) printf(" -"); else printf(" +", i); } test 3: err=0.352941 - test 5: err=0.588235 - test 7: err=0.823529 - test 9: err=0.0588235 - test 11: err=0.294118 - test 13: err=0.529412 - test 15: err=0.764706 - test 17: err=0 + test 19: err=0.235294 - test 21: err=0.470588 - test 23: err=0.705882 - test 25: err=0.941176 - test 27: err=0.176471 - test 29: err=0.411765 - test 31: err=0.647059 - test 33: err=0.882353 - test 35: err=0.117647 - test 37: err=0.352941 - test 39: err=0.588235 - test 41: err=0.823529 - test 43: err=0.0588235 - test 45: err=0.294118 - test 47: err=0.529412 - test 49: err=0.764706 - test 51: err=0 + test 53: err=0.235294 - |
Сообщ.
#65
,
|
|
|
Ну, я такой алгоритм предлагал парой десятков постов выше. Работает, но полным перебором и может зациклиться (не остановиться).
|
Сообщ.
#66
,
|
|
|
В общем, если такая функция нужна, то нет проблем её написать. Но пока я знаю только двух человек, которые ею заинтересовались. Причём подозреваю, если они её напишут, то после более тесного знакомства с нею они начнут ругать всех остальных здесь присутствующих за то, что те недостаточно активно их отговаривали от такого опыта.
Такая функция выглядит неплохо в качестве умозрительных рассуждений или в качестве упражнения по программированию. В реальном коде она окажется источником плохо диагностируемых ошибок. |
Сообщ.
#67
,
|
|
|
А я вот сходу не вижу возможности написание оной за приемлемое для расчёта время. Как быстро "угадать", что знаменатель в несократимой дроби - нечётен? Непонятно.
Добавлено Впрочем, не, всё понятно. 10k раскладывается же на 2k*5k, а деление целого на 2 - тривиальная задача. Так что всё заработает весьма быстро. Добавлено Эх, в моём варианте функции (a'la double pow( double x, строка степень) ) всё равно не получится вычислить (-8)-1/3, ибо 1/3 запишется как 0.3333...333, а это означает, что равно 333...333/10k, а значит знаменатель - чётен. Проблема, блин. |
Сообщ.
#68
,
|
|
|
Если пересмотреть формат хранения дробей, как двух целых - числитель и знаменатель, будет достаточно определить, что в числителе больше двоек-множителей, чем в знаменателе, то есть дробь сократима до нечётного знаменателя.
|
Сообщ.
#69
,
|
|
|
Да, согласен. Но вся беда в том, что для практического применения сей способ никак не годится. Ни за что (в практических целях) не будут вызывать функцию с числителем и знаменателем. Увы. А вот pow(-8, "0.(3)") ещё есть шанс, но тоже не ахти. Эх, не придумывается универсализм.
|
Сообщ.
#70
,
|
|
|
Цитата Mikle @ А не проще ли соератить дробь и посмотреть чётность знаменателя. Разложение на множители - довольно трудоёмкий процесс. Впрочем, максимальная степень 2 выделяется быстро. будет достаточно определить, что в числителе больше двоек-множителей, чем в знаменателе, |
Сообщ.
#71
,
|
|
|
Цитата amk @ А не проще ли соератить дробь и посмотреть чётность знаменателя. Разложение на множители - довольно трудоёмкий процесс. В том то и дело, что полное сокращение не требуется, достаточно сократить двойки. Цитата amk @ максимальная степень 2 выделяется быстро Даже очень быстро, есть инструкция ассемблера, "bsf" или "bsr", не помню, ищет индекс первого справа установленного бита. Это и есть число двоек делителей. |
Сообщ.
#72
,
|
|
|
Даже если такой инструкции нет, младший бит можно выделить выражением (n&-n)
|