using exponents with float

Blitz3D Forums/Blitz3D Programming/using exponents with float

_33(Posted 2007) [#1]
I've found that I can't substitute de C++ function pow() with the exponent of blitz3D.

Print 1.0^0.9
WaitKey()

This gives a 1.0 result, which is wrong. Is there a way around this?

EDIT: might not be wrong, but I have a problem with my exponent handling.


H&K(Posted 2007) [#2]
1^X is always 1, even if X is zero.

Print 2.0^0.9
gives 1.86607 which is also right


_33(Posted 2007) [#3]
I'll meditate on that. I'm trying to find my problem... because it might be in the conversion of my pow() instructions.

This is the C++ code:
R = pow(R, 0.9) / pow(1, 0.9);
G = pow(G, 0.9) / pow(1, 0.9);
B = pow(B, 0.9) / pow(1, 0.9);


This is my Blitz3D code:
r = (r^0.9) / (1.0^0.9)
g = (g^0.9) / (1.0^0.9)
b = (b^0.9) / (1.0^0.9)


If I don't normalize my RGB value with this, it's all fine, when I do, I get outrageous results. It should of given me very subtile differences.

I'll continue looking, I'm not sure anymore.


H&K(Posted 2007) [#4]
From ms-help://MS.VSExpressCC.v80/MS.NETFramework.v20.en/cpref2/html/M_System_Math_Pow_1_f9e719c8.htm
Return Value
The number x raised to the power y. The following table indicates the return value when various values or ranges of values are specified for the x and y parameters. For more information, see Double.PositiveInfinity, Double.NegativeInfinity, and Double.NaN.
Parameters
Return Value

x or y = NaN
NaN

x = Any value except NaN; y = 0
1

x = NegativeInfinity; y < 0
0

x = NegativeInfinity; y is a positive odd integer
NegativeInfinity

x = NegativeInfinity; y is positive but not an odd integer
PositiveInfinity

x < 0 but not NegativeInfinity; y is not an integer, NegativeInfinity, or PositiveInfinity
NaN

x = -1; y = NegativeInfinity or PositiveInfinity
NaN

-1 < x < 1; y = NegativeInfinity
PositiveInfinity

-1 < x < 1; y = PositiveInfinity
0

x < -1 or x > 1; y = NegativeInfinity
0

x < -1 or x > 1; y = PositiveInfinity
PositiveInfinity

x = 0; y < 0
PositiveInfinity

x = 0; y > 0
0

x = 1; y is any value except NaN
1


x = PositiveInfinity; y < 0
0

x = PositiveInfinity; y > 0
PositiveInfinity

So Basicly Pow (1,0.9) = 1, so you dont need /pow(1,0.9) at all.
Something fishy is going on there.
I look forward to the anwser ;)


_33(Posted 2007) [#5]
Here's the complete test:



H&K(Posted 2007) [#6]
lol,

I dont know what its supposed to look like, but it looks the same to me with or without the /(1.0^0.9)s


_33(Posted 2007) [#7]
Yes you are right, I took it from the C code from the MESS emulator. And so it's a direct conversion. I'm trying to find out what is going on with my colors. if you remove the adjust portion of the RGB (^0.9), you'll notice the difference, which should be subtile. But, it is not.

This is a color table, which should scale from dark tones (left) to bright tones (right).




_33(Posted 2007) [#8]
Here's something:
r# = -0.1
r = r^0.9
Print r
rr% = r * 255.0
Print rr
WaitKey()


I'll have to prevent this from happening.


Floyd(Posted 2007) [#9]
Whatever this is supposed to be doing it is clear that clamping r,g,b to the range 0 to 1 like this:

If (r < 0) Then r = 0 ElseIf (r > 1) Then r = 1

must be done before r^0.9. A value like (-0.1)^0.9 is not even defined. Just try Printing it.

And you can throw away the / (1.0^0.9) as it is utterly pointless.

With those changes your test becomes

Graphics 1024,768
For ii = $0 To $0F
   Locate 0,ii * 48
   For ij = $00 To $F0 Step $10
      res = gtia_to_rgb(ii+ij)
      r = res Shr 16
      g = res Shr 8 And $FF
      b = res And $FF
      Color r, g, b
      Rect (ij Shr 4) * 64, ii * 48, 64, 48, 1
      Color 128,128,128
      Write Right$(Hex$(ii+ij), 2) + Right(Hex$(res), 6)
   Next
   Print
Next
WaitKey()

Function gtia_to_rgb(val%)
   Local i#, q#

   lm# = (val Shr 4) And $0F
   cr# = val And $0F
   Select cr
      Case 0 : i = 0.000 : q = 0.000
      Case 1 : i = 0.144 : q = -0.189
      Case 2 : i = 0.231 : q = -0.081
      Case 3 : i = 0.243 : q = 0.032
      Case 4 : i = 0.217 : q = 0.121
      Case 5 : i = 0.117 : q = 0.216
      Case 6 : i = 0.021 : q = 0.233
      Case 7 : i = -0.066 : q = 0.196
      Case 8 : i = -0.139 : q = 0.134
      Case 9 : i = -0.182 : q = 0.062
      Case 10: i = -0.175 : q = -0.022
      Case 11: i = -0.136 : q = -0.100
      Case 12: i = -0.069 : q = -0.150
      Case 13: i =  0.005 : q = -0.159
      Case 14: i =  0.071 : q = -0.125
      Case 15: i =  0.124 : q = -0.089
   End Select
   y# = lm / 15.0
   r# = y + 0.956 * i + 0.621 * q
   g# = y - 0.272 * i - 0.647 * q
   b# = y - 1.106 * i + 1.703 * q

   If (r < 0) Then r = 0 ElseIf (r > 1) Then r = 1
   If (g < 0) Then g = 0 ElseIf (g > 1) Then g = 1
   If (b < 0) Then b = 0 ElseIf (b > 1) Then b = 1

   r = r^0.9
   g = g^0.9
   b = b^0.9

   Return (((Int(r * 255.0)) Shl 16) Or (((Int(g * 255.0)) Shl 8) Or Int(b * 255.0)))
End Function



_33(Posted 2007) [#10]
Floyd, I rewrote a C++ palette assignment routine originally found in the source of the MESS emulator, into Blitz3D code. The R G B handling in the original C++ code was using doubles. The R G B clamping was done originally after the exponent code. They used pow(1.0,0.9) orignally, which I converted without asking, as this was taken from working C++ code.

Cheers.


Floyd(Posted 2007) [#11]
I don't know about the MESS emulator but I can promise you that raising a negative number to the 0.9 power does not make sense.

Print -0.1 ^ 0.9
WaitKey
The displayed NaN means Not a Number, i.e. -0.1 ^ 0.9 does not have any numerical value.

This is why the clamping must be done before the exponent code.


_33(Posted 2007) [#12]
Thank you Floyd and also H&K for clearing all this out.

Regards.