Render.ru

Ограничения maxscript

aly8

Активный участник
Рейтинг
10
#1
Уважаемые спецы, помогите пожалуйста разобраться с точностью расчетов в maxscript.

Почему бесконечно малые меньше 1e-8 уже отображаются как 0.0? при этом числа с положительной степенью легко доходят до 1.0e+38.
возможно ли, вообще, получать числа с большими отрицательными степенями?

И еще вопрос. Вот небольшой пример:
(
clearlistener()
local aaa = 1000000.0
for k = aaa/10.0 to aaa by aaa/10.0 do
(
local a = 0.0
for i = 1.0 to k do a = a + 1.0/k
format "%: % = 1.0 - %\n" (num*k) a (a==1.0)
)
)
суть в том, что должно, по идее, получаться 1.0 = 1.0, в итоге везде false, даже при aaa = 100. Что с цифрами? возможно ли повысить точность расчетов?
 

aly8

Активный участник
Рейтинг
10
#3
спасибо за цитаты, диапазоны впечатляют!, но все же...

откуда берется погрешность? (см. картинку) никак не могу от нее избавиться

На картинке для сравнения тот же блок на С++ абсолютно без погрешности, как и предполагалось.
скрипт с картинки:
(
clearlistener()
local a = 0.0, num = 1.0e+07,
start = timeStamp()

for i = 1.0 to num do a+= 1.0/num

local end = timeStamp()
print a
format "Processing took % seconds\n" ((end - start) / 1000.0)
)


п.с. прошу прощения, в первом сообщении нужно удалить из кода параметр num
 

Вложения

Savin Denis

Модератор форума
Команда форума
Рейтинг
138
#4
Да

Код:
a = 0.0
for i = 1 to 20 do a += 0.05
a == 1.00000006
[color=Blue]true[/color]

a = 1.0
for i = 1 to 20 do a -= 0.05
a
[color=Blue]-1.56462e-007[/color]
Да поздравляю ты нашел, багу.
Проверь еще последнем максе со всеми фиксами.

Отпишись напиши на форуме autodesk`a
Если есть лицензия то сразу в сапорт.


PS
Пока могу посоветовать для повышения точности расчетов сдвигать дробные в целые.
 

aly8

Активный участник
Рейтинг
10
#5
похоже нашлось решение :D
погрешность дают числа float

----выдержка из хелпа-------
Input Value 1.23456789

Stored Value 1.23456788

Displayed Value 1.23457

или
Input Value 1.1

Stored Value 1.10000002

Displayed Value 1.1

для точных расчетов надо использовать числа double

a = double 1.0
for i = 1 to 20 do a -= 0.05
a
-- a = 0.0d0

зачем только такое ограничение, не совсем ясно. На времени расчета не сказывается
 

Savin Denis

Модератор форума
Команда форума
Рейтинг
138
#6
Погрешность все равно будет просто меньше

Код:
a = double 1.0
for i = 1 to 20 do a -= 0.05d0
a
a == 0.0d0
[color=Blue]false[/color]
 

aly8

Активный участник
Рейтинг
10
#7
опять непонятки
помогите пожалуйста разобраться!

1. почему на выходе совсем другое число?
Код:
v = double 1.1111111111111111
formattedPrint v format:"1.100g" 
--v = "1.1111111640930176"
2. удивительно, но так работает
Код:
0.000000000000000000000000000001d+030
--otvet = 1.0d0
3. вот еще, как, к примеру, записать точные данные в файл?
Код:
(
output_name = getSaveFileName caption:"SpeedSheet File" types:"SpeedSheet (*.txt)|*.txt|All Files (*.*)|*.*|"
 if output_name != undefined do
	 ( output_file = createfile output_name
		local a = double 0.0
		for i = 1 to 20 do
		(
			a += double 0.00000001
			format "a =  %\n" a to:output_file 
			)			 
		 close output_file
		 edit output_name
	 )
	)
в итоге опять получаются вместо малых значений - нули

Денис спасибо за советы, но софт н.л. и по английски читаю то со словарем, а письма писать еще сложнее.
 

Savin Denis

Модератор форума
Команда форума
Рейтинг
138
#9
1. По тому что задаешь костанту во float
3. Смотри 1., преобразуй в строку через formattedPrint, format обрежет до 7 знака
 

aly8

Активный участник
Рейтинг
10
#10
спасибо.
класс!
действительно, значит нужно задавать значения именно таким образом:
Код:
v = 1.1111111111111111d0
formattedPrint v format:"1.100g" 
--v = "1.1111111111111112"
вах, вах, вах, вроде заработало!:)
 

aly8

Активный участник
Рейтинг
10
#11
следующая проблема.
Возможно ли задавать малые приращения объекту с точностью, как в предыдущем сообщении

Вот к примеру код:

Код:
(
	clearlistener()
	local delta = 0.000001d0
	try(delete $Dummy*)catch()
	local theD = dummy pos: (random [-10.0,-10.0,-10.0] [10.0, 10.0, 10.0])
	local a = formattedPrint theD.pos.z format:"1.100g" 
	theD.pos.z = theD.pos.z  + delta
	local b = formattedPrint theD.pos.z format:"1.100g" 
	print a
	print b
)
логично предположить, что объект должен получать приращения не больше delta = 0.000001d0, а опять получается какая-то неразбериха.
у меня получились такие значения:
Код:
"0.7070564 6 276473999"
"0.7070574 7 604370117"
"0.7070574 7 604370117"
странно, но после "7" цифры стали скакать - по какому закону? Мало того, бывает и так, что приращение получается совсем не равное delta = 0.000001d0 8)

И еще, Денис, не подскажешь, возможно ли вообще maxscript вывести на уровень с максимально точными значениями ВСЕХ переменных, будь то вектора, позиции и прочее..? А то уже устал. Мало того, что сами по себе численные методы содержат в себе неточности, так еще и maxscript добавляет..
 

Savin Denis

Модератор форума
Команда форума
Рейтинг
138
#12
Нет, все координаты имеют тип Float
Форматы повышенной, точности изначально не используются в максе, введены для совместимости обмена данными с NET. приложениями
 

aly8

Активный участник
Рейтинг
10
#13
Спасибо за исчерпывающий ответ!

Тут сам собой следующий вопрос возник:

Позволяет ли maxscript управлять нагрузкой на ядра во время расчетов?

Дело в том, что , к примеру, на 4-х ядерной машине(windows 64bit не виста) при расчетах используется только одно ядро. Там как-то хитро так сделано, что нагрузка постоянно перераспределяется, но в итоге проц все равно используется только на 25%
 

Savin Denis

Модератор форума
Команда форума
Рейтинг
138
#14
Нет, нельзя, система сама решает. какую нагрузку отхапать. Все это касается только ядра системы, внешние рендеры сами решают вопрос с загрузкой проца.
Все что можно, см в гл. System Information

Хотя как только появилась 64 версия, был неофициальный патчь на эту тему. Но потом не видел.
 
Сверху