Render.ru
Поддержать

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

aly8

Активный участник
Рейтинг
10
Уважаемые спецы, помогите пожалуйста разобраться с точностью расчетов в 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. Что с цифрами? возможно ли повысить точность расчетов?

Savin Denis

Модератор форума
Команда форума
Рейтинг
138
A Float in MAXScript has an absolute value range of is 1.18E-38 to 3.40E38, with a precision of one part in 1.0E7.
When you display or print a Float, MAXScript prints the value to the 6th significant digit.

aly8

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

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

На картинке для сравнения тот же блок на С++ абсолютно без погрешности, как и предполагалось.
скрипт с картинки:
(
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
Да

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
похоже нашлось решение 😃
погрешность дают числа 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
Погрешность все равно будет просто меньше

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

aly8

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

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
	 )
	)
в итоге опять получаются вместо малых значений - нули

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

aly8

Активный участник
Рейтинг
10
Погрешность все равно будет просто меньше
ага, емае.

Savin Denis

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

aly8

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

aly8

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

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

(
	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
Нет, все координаты имеют тип Float
Форматы повышенной, точности изначально не используются в максе, введены для совместимости обмена данными с NET. приложениями

aly8

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

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

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

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

Savin Denis

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

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