【问题标题】:CInt not working as expected in .Net MFCInt 在 .Net MF 中没有按预期工作
【发布时间】:2012-02-06 23:24:43
【问题描述】:

我有一些相当不错的东西可以交叉淡化 RGB LED 的颜色,但我无法获得所需的值。

我已将这个示例精简到最低限度,但 StartEndSteps 都将是可变的...

应该以 100 步线性递增 R (UInt) 从 0 到 255。我不太担心这里的精度,所以我真的不在乎它是否正确舍入或只是做一个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

这个输出:

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

如您所见,Temp 变量非常正确,允许有一些不精确,但我看不出与 R 的相关性。

CUint 可能只是读取 Temp 位并将Double 视为UInt - 但如果是这样,我如何让它正确转换?

(顺便说一下,这是在netduino 上运行的),.Net Micro Framework 4.2

编辑:下面要求的测试:

    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

使用下面的代码...

    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

我得到(在Dim Temp 线上):

An unhandled exception of type 'System.Exception' occurred in Netduino_VBTest.exe

没有内部异常,但在输出的上方是第一次机会异常,我猜这是根本原因:

A first chance exception of type 'System.NotImplementedException' occurred in Microsoft.SPOT.Native.dll

【问题讨论】:

    标签: .net types .net-micro-framework netduino


    【解决方案1】:

    尝试使用 Convert.ToUInt32,此处概述:http://msdn.microsoft.com/en-us/library/y3569ft9.aspx

    在 Windows 7 64 位上的 .Net 4.0(不是 Micro)上,我没有看到您使用 CInt/CUInt 看到的内容(我的转换正确)。这可能是 netduino/微框架中的一个实现错误......如果我有它,我会为你测试上述内容。

    【讨论】:

    • 我不相信它存在于微框架中——除非它被埋在一个奇怪的命名空间中?我有一个Convert.ToUInt32,但它只有 1 个带有String 类型参数的重载。 Convert.ToUInt32(Temp.ToString) 导致 An unhandled exception of type 'System.Exception' occurred in mscorlib.dll
    • 这不是netduino本身,如果有的话,它是仍然非常粗糙的.Net Micro Framework - 如果我使用.NetMF提供的模拟器,我会得到同样的结果。
    • 顺便说一下,我也是Win7x64,.Net4,VS2010
    • 对不起,我不在 Micro Framework 上。我刚刚安装它以便我进行调查。
    • 嗯。我刚刚重新启动 VS 并再次将其设置为模拟器 - 现在它可以在 Emu 上运行,但不能在 netduino 上运行?!?也许你是对的,这是一个 netduino 问题。我在他们的论坛上提到过...forums.netduino.com/index.php?/topic/…我很想知道你得到了什么。
    【解决方案2】:

    无论发生什么,我都建议您尽可能避免使用 UInts(我去过那里)。我会这样写代码:

    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
    

    由于没有可用的Vb.Net编译器,我无法尝试,并且我已经直接在SO上编写了代码,如果有任何编译错误请见谅。

    【讨论】:

    • 不用担心,让我测试一下 - 我也不是特别喜欢 UInts,但这是硬件需要的... Start 正在从硬件中读取为 UInt,End 由用户提供但是写和你读的一样的类型是有意义的……
    • 使用您的转换 CType(Temp, UInteger) 并将结果存储在 R 中,我得到完全相同的结果。我不相信 StartEnd 是问题,因为 Temp 设置正确 - 它只是将 that 转换为 UInt 这有点粘
    • 这里的一件事是 Temp 不是双精度而是整数。你能用 CType 给我写一个 Int 及其对应的 UInt 转换吗?
    • 代码不会编译,因为 Temp= 公式的 R.H.S 会导致双精度。 (我有 Strict on - 没有从 Double 到 Int 的隐式转换)。我将在 2 秒内编辑一些测试 CInt()s...
    • ([End] - Start) \ Steps * x + Start 必须返回一个整数。请注意,我使用的是运算符 \ 而不是运算符 /。
    【解决方案3】:

    另一种完全不同的方法。由于问题看起来与双打和转换有关,我们可以避免双打只做减法:

    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
    

    又快又脏,但它有效。

    【讨论】:

    • 没错 - 让我玩一玩。我不是这样的粉丝,因为我希望这都是可变的,并且硬编码增量是一个问题(我无法计算增量,因为它会是双倍!)
    【解决方案4】:

    怎么样

    Debug.Print(Test.ToString().Split("."c)(0))
    

    我还没有解决任何极端情况,但这适用于我尝试的几个示例。如果必须在循环中执行此解决方案,我不会推荐此解决方案,因为它不会很好地执行,但它可能是一个权宜之计,直到您找到更好的东西。

    【讨论】:

    • 这...Debug.Print(UInteger.Parse(Test.ToString().Split("."c)(0)).ToString) 似乎有效 - 我将把它包装在一个函数中。同意它的性能不高,但至少它有效
    猜你喜欢
    • 2014-01-26
    • 2021-10-19
    • 2020-03-18
    • 2012-06-14
    • 2014-11-15
    • 1970-01-01
    • 2012-07-02
    • 2011-09-07
    • 2013-03-03
    相关资源
    最近更新 更多