CInt not working as expected in .Net MF
-
15-04-2021 - |
سؤال
I've got something pretty noddy to cross-fade the colour of an RGB led and I'm having problems getting the desired values.
I've stripped this example down to a bare minimum but Start
, End
and Steps
will all be variable...
This should linearly increment R
(UInt) from 0 to 255 in 100 steps. I'm not too worried about precision here so I don't really care if it rounds properly or just does a Floor
/Ceiling
Dim Start As UInteger = 0
Dim [End] As UInteger = 255
Dim Steps = 100
For x = 1 To Steps
Dim Temp = ([End] - Start) / Steps * x + Start
Dim R = CUInt(Temp)
Debug.Print(x.ToString & ": Temp: " & Temp.ToString & ", R:" & R.ToString)
LedR.SetPulse(255, R)
Threading.Thread.Sleep(20)
Next
This Outputs:
1: Temp: 2.5500, R:196608
2: Temp: 5.1000, R:327680
3: Temp: 7.6500, R:524288
4: Temp: 10.2000, R:655360
5: Temp: 12.7499, R:851968
...
95: Temp: 242.2488, R:15859712
96: Temp: 244.7988, R:16056320
97: Temp: 247.3488, R:16187392
98: Temp: 249.8988, R:16384000
99: Temp: 252.4488, R:16515072
100: Temp: 254.9988, R:16711680
As you can see, the Temp variable is pretty-much correct, allowing for some slight imprecision but I can't see what the correlation is with R
.
It's possible that CUint is simply reading the bits for Temp and treating the Double
as a UInt
- but if so, how do I get it to convert it correctly?
(Incidentally, this is running on a netduino), .Net Micro Framework 4.2
Edit: Tests requested below:
Dim Test As Integer = 2
Debug.Print(Test.ToString)
Debug.Print(CInt(Test).ToString)
Debug.Print(CUInt(Test).ToString)
2
2
2
Dim Test As Double = 2.5
Debug.Print(Test.ToString)
Debug.Print(CInt(Test).ToString)
Debug.Print(CUInt(Test).ToString)
2.5000
131072
131072
Using the following code...
For x = 0 To Steps
Dim Temp As Long = ([End] - Start) \ Steps * x + Start
Dim R = CType(Temp, UInteger)
Debug.Print(x.ToString & ": Temp: " & Temp.ToString & ", R:" & R.ToString)
LedR.SetPulse(255, R)
Threading.Thread.Sleep(20)
Next
I get (on the Dim Temp
line):
An unhandled exception of type 'System.Exception' occurred in Netduino_VBTest.exe
There's no inner exception but just above it in the output is a first chance exception which I'm guessing is the root cause:
A first chance exception of type 'System.NotImplementedException' occurred in Microsoft.SPOT.Native.dll
المحلول
Try using Convert.ToUInt32, outlined here: http://msdn.microsoft.com/en-us/library/y3569ft9.aspx
On my .Net 4.0(not Micro) on Windows 7 64bit I am not seeing what you are seeing with CInt/CUInt (mine converts properly). This may be an implementation error in netduino/the Micro Framework... If I had it I would test the above for you.
نصائح أخرى
Whatever is happening I would advise you to avoid UInts as much as you can (I've been there). I would write the code like this:
Dim Start As Integer = 0
Dim [End] As Integer = 255
Dim Steps As Integer = 100
For x As Integer = 1 To Steps
Dim Temp As Integer = ([End] - Start) \ Steps * x + Start
LedR.SetPulse(255, CType(Temp,UInteger))
Threading.Thread.Sleep(20)
Next
I cannot try it because I have not the Vb.Net compiler available and I've wrote the code directly on SO, please forgive me if there are any compilation errors.
Another approach completely different. As the problem looks to be with doubles and conversions we could avoid doubles doing only subtracts:
Dim Start As Integer = 0
Dim [End] As Integer = 255
Dim Increment As Integer = 3
Dim Current as Integer = Start
While Current < End
Current = Current + Increment
LedR.SetPulse(255, CType(Current ,UInteger))
Threading.Thread.Sleep(20)
End While
Quick & Dirty but it works.
How about
Debug.Print(Test.ToString().Split("."c)(0))
I have not worked out any edge-cases, but this worked on a couple of examples I tried. I would not recommend this solution if this will have to be performed in a loop as it will not perform well, but it might be a stop-gap until you can find something better.