Anyone got a good maths head?
Blitz3D Forums/Blitz3D Programming/Anyone got a good maths head?
| ||
Need a very quick way of averaging 2 32bit argb hex numbers: ie: print averagehex($FFFFFFFF,$00000000) returns: $80808080 I can do i by breaking it down but may be a bit slow for what i need |
| ||
Hex is only a way of representing a number, so you can use the following: Print Hex((n1+n2)/2) |
| ||
wont that cause a 32bit integer overflow |
| ||
First up, the average above should be $80000000 (or $7FFFFFFF if rounding down) Next, you can treat each hex digit completely separately due to the x16 nature of each 'nybble' which will half exactly when averaging. so... any scheme which averages each hex pair can be used as long as the strings are the same length option 1: add the two digits and half them {problem... you need to add 'letter' digits} option 2: given any two digits, move progressively towards the 'middle' value by +1 to lowest and -1 to highest until they meet. I don't have time to code one, but I think you should be able to work one up from here... {That lot off the top of my head, so I wouldn't bet the mortgage on it... e.g. the bit about separating digits might be subject to revision where 'rounding' occurs or where they don't 'meet' but cross over instead} |
| ||
Might if you're using stupidly high numbers, but for the most part it'll work. Alternatively try Print Hex(n1+(n2/2)). Don't have Blitz on this PC so I can't test stuff. [edit]Also depends whether you want median or mean average. They aren't the same. |
| ||
80000000! (oh yeah... (slap on head) :) thats what i thought, ive done it byte for byte. It wasnt as slow as i thought itd be :P thanks |
| ||
"Might if you're using stupidly high numbers, but for the most part it'll work. Alternatively try Print Hex(n1+(n2/2))." I am using stupidly high numbers ;) |
| ||
Alternatively try Print Hex(n1+(n2/2)) misplaced bracket in there ! Alternatively try Print Hex((n1+n2)/2) |
| ||
misplaced bracket in there ! Nope. I want to divide n2 first. Its correct. |
| ||
@GfK: n1 = 4; n2 = 6 .... average is 5 but n1 + (n2/2) = 4 + 6/2 = 4 + 3 = 7 .... I beg to differ ! (n1 + n2)/2 = (4 + 6)/2 = 10/2 = 5 |
| ||
Well maybe the maths was wrong (I did say I hadn't tested it at all), but its as I intended it at the time. Should've been n1+((n2-n1)/2) |
| ||
avg(a,b) = (a + b) / 2 = a/2 + b/2 When using integer arithmetic you have to be careful of the rounding in intermediate results. So: a:Int = 1234567 b:Int = $12345678 Print Hex((a + b) / 2) ' Simplistic but may overflow Print Hex((a shr 1 + b shr 1)) ' Close but may be out by 1 ' This is the correct solution Print Hex(a Shr 1 + b Shr 1 + ((a & $01) + (b & $01)) Shr 1) |
| ||
The above is expressed in BlitzMax as I don't have Blitz3D. The syntax will not work exactly but the intent certainly should. (Note to self - check which forum the post is in) |
| ||
That's a very nice solution PGF... the bitmask part on the end is very elegant. |