So let me summary best of Thomas idea (Yes bitRake I found a flow in you solution)
1. we can use register as a ponter to decrease size of fpu proc
2. We should load lowest possible address of variables used
Why - 'cause negative value to shift from the base will result
in bigger opcode (shift value)
In our case lowest is x that is value we need to load as "base pointer"

.data?
x dd ?; % of salt
y dd ?; new % of salt
w real4 ? ;weight of mixture
watertoadd real4 ? ; how many water to add to decrease % f salt
;in the mixture


mov eax, offset x ; /lea eax, w
;st(0) st(1) st(2)
fld real4 ptr ;w
fidiv dword ptr ;w/y
fimul dword ptr ;w*x/y
fsub real4 ptr ;w*x/y-w
fstp real4 ptr ;.

I have no asm or debuger on the computer I'm posting from
so correct me if I've made a mistake somewhere here :)
Posted on 2002-02-08 12:05:07 by The Svin
It works for all memory values but it depends on their memory locations whether it can benefit from it.
I don't think it can get much smaller than this.. How about speed? How should we measure it? Just a 1.000.000x loop with rdtsc?

Thomas
Posted on 2002-02-08 12:05:41 by Thomas

So let me summary best of Thomas idea (Yes bitRake I found a flow in you solution)
Sorry, I correct initial post moment after first post - refresh your browser. :)

Speed? What CPU? Best time would work for some algos, other would need average on a range of inputs (random/ordered?)
Posted on 2002-02-08 12:09:42 by bitRAKE
The Svin: Why - 'cause negative value to shift from the base will result in bigger opcode (shift value)


Actually bitRAKE's version is one byte smaller (18 bytes against 19 bytes for your one).. Negative shift values do not result in bigger opcodes:



.0040110F: B828404000 mov eax,000404028 ;" @@("
.00401114: D900 fld d,[eax]
.00401116: DA70FC fidiv d,[eax][-0004]
.00401119: DA48F8 fimul d,[eax][-0008]
.0040111C: D820 fsub d,[eax]
.0040111E: D95804 fstp d,[eax][00004]


Thomas
Posted on 2002-02-08 12:40:35 by Thomas
You're right, Thomas.
And then you should explain, why it's shorter :)
And basic rules to follow using reg as pointer to make the smallest possible code.
I also asking you, since from my point of view you made optimal math formula, to explain this parts relative task from arithmetic point of view.

to Rake and other modes:
my be with the rest tasks we shall proceed to Algo section?

Two new tasks derived from the previous.
1. Write code (as fast as possible - remember of the first solution score)
that calculate how much salt you need to add to make procentage
of salt to given percent.
variables the same.
2. Write dialog that receives user input of current of weight of mixture and percent of one of component.
And percent of the component the user want to get in future mixture. (For simplicity we may stay with salt and water mixture
but it's clear that the dlg may be used for any components and
the dlg will have a real practical value in many house work, cooking and ect. tasks)
Depending on if value of willing percentage is bigger or lower the dlg must give answer of how much water or salt the user need to
add to get x% of salt (or anything else) mixture.
Posted on 2002-02-08 15:19:24 by The Svin
I'll write some explaination for the algo and as well look at the new tasks tomorrow, I don't have much time now so I won't be the first on this one.
I have figured out a new task though, I will post it in the algorithm section right now before I go.

Thomas
Posted on 2002-02-08 15:25:01 by Thomas
For the first task:

x: % of salt
y: wanted % of salt
add: kg of salt to add
w: weight of current mixture
----
temp vars used in algorithm below:
ns = total weight (kg) of salt in new mixture
os = weight of salt in old mixture
nw = total weight of new mixture
---
algo:


y = ns/nw * 100 <-> ns = y*nw / 100 (1)
os = w*x / 100 (2)
add = ns - os (3)

(1),(2),(3)-->
add = y*nw / 100 - w*x/100 = (y*nw - x*w)/100 (4)

nw = w + add (5)

(4)&(5)-->
add = (y*(w+add) - x * w) / 100
<->
(y*(w+add) - x*w - 100*add)) / 100 = 0
<->
y*w + y*add - x*w - 100*add = 0
<->
w*(y - x) + add*(y - 100) = 0
<->
add = (-w*(y-x)) / (y - 100)
= [b]w*(y-x) / (100 - y)[/b]


The code is:


I gave the vars some values for testing:
[b].data[/b]
x dword 4.0
y dword 8.0
w real4 7.0
;output:
salttoadd real4 0.0

;used in algo:
r100 real4 100.0

[b].code[/b]

;st0 st1
mov eax, offset y ;. .
fild dword ptr [eax] ;y .
fisub dword ptr [eax-4] ;y-x .
fld real4 ptr [r100] ;100 y-x
fisub dword ptr [eax] ;100-y y-x
fdiv ;(y-x)/(100-y) .
fmul real4 ptr [eax+4] ;w*(y-x)/(100-y) .
fstp real4 ptr [eax+8] ;. .


The code is 26 bytes and roughly 18~19 cycles (on my athlon thunderbird).


Thomas
Posted on 2002-02-09 04:21:17 by Thomas