在C#中添加长而粗的东西 [英] Add a long and ulong in C#

查看:93
本文介绍了在C#中添加长而粗的东西的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用的api有一个ulong字段(我无法更改此字段).我需要通过long量来调整该字段(也可以是int).但是我不能将这些添加到一起:Operator '+' is ambiguous on operands of type 'ulong' and 'long'.

An api I am using has a ulong field (I can't change this). I need to adjust this field by the a long amount (could be an int too). However I can't add these togeather: Operator '+' is ambiguous on operands of type 'ulong' and 'long'.

我不能将long转换为ulong,因为我会丢失符号,我无法将ulong转换为long,因为我可能会丢失部分值.

I can't convert the long to a ulong because I will lose the sign, I can't convert the ulong to a long because I could lose part of the value.

如果要导致换行,我最终想尝试调整该值,而我想返回false而没有完成调整.如果没有包装,我要完成调整并返回true;否则,返回true.我可以做这部分,但前提是我首先想出一种将两个字段加在一起的方法.

Ultimately I want to attempt to adjust the value, if it would cause a wrap I want to return false and not finish the adjustment. If it doesn't wrap I want to finish the adjustment and return true; I can do this part, but only if I can figure out a a way to add the two fields together in the first place.

public ulong Value;
public bool AdjustValue(long amount)
{
    // Operator '+' is ambiguous on operands of type 'ulong' and 'long'
    ulong adjustValue = Value + amount; 

    if (amount < 0 && adjustValue > Value)
        return false;
    if (amount > 0 && adjustValue < Value)
        return false;

    Value = adjustValue;
    return true;
}

我该如何解决?

推荐答案

出于可读性考虑,您可能更喜欢注释中的建议:

For readability, you may prefer the suggestion in the comment:

adjustValue = Value;
if (amount < 0)
    adjustValue -= (ulong)(-amount);
else
    adjustValue += (ulong)amount;

这清楚地表明了您期望数学如何工作.

This makes clear how you expect the math to work.

但是…

However…

几乎每个现代硬件CPU中的整数表示都是2的补码.原因之一是使用二进制补码二进制数的数学运算具有很好的性质:无论是处理有符号值还是无符号值,您都可以使用相同的二进制表示法进行加减运算.

The representation of integers in practically every modern hardware CPU is two's complement. One of the reasons is that math using two's complement binary numbers has a very nice property: you get the same binary representation for addition and subtraction whether you're dealing with signed or unsigned values.

这意味着您只需将调整值转换为ulong即可进行添加.根据C#语言规则,强制转换将仅将有符号值的二进制表示形式重新解释为无符号.并且添加无符号值将具有与添加具有相同二进制表示形式的有符号值完全相同的效果.

This means that you can just cast the adjustment value to ulong to do your addition. According to the C# language rules, the cast will simply reinterpret the signed value's binary representation as unsigned. And adding the unsigned value will have exactly the same effect as if you'd added a signed value with that same binary representation.

这是一个显示此工作原理的代码示例:

Here's a code example that shows this working:

static void Main(string[] args)
{
    ulong[] values = { ulong.MinValue, ulong.MaxValue, long.MaxValue };
    long[] adjust = { 0, 1, -1, long.MinValue, long.MaxValue };

    for (int i = 0; i < values.Length; i++)
    {
        for (int j = 0; j < adjust.Length; j++)
        {
            ulong value = values[i];

            bool result = AdjustValue(adjust[j], ref value);
            Console.WriteLine($"{values[i]} + {adjust[j]} = {values} (overflow: {!result})");
        }
    }
}

static bool AdjustValue(long amount, ref ulong value)
{
    ulong adjustValue = value + (ulong)amount;

    if (amount < 0 && adjustValue > value)
        return false;
    if (amount > 0 && adjustValue < value)
        return false;

    value = adjustValue;
    return true;
}

注意:默认情况下,未选中运行时的数学运算.但是,有一个编译器开关可以更改此设置.如果要在启用该开关的情况下编译代码,并强制执行已检查的算术运算,则需要将以上内容包装在unchecked块中,以免发生溢出异常.

Note: by default, math operations are runtime are unchecked. However, there is a compiler switch that can change this. If you are compiling your code with that switch enabled, forcing checked arithmetic operations, you will need to wrap the above in an unchecked block to avoid getting overflow exceptions.

这篇关于在C#中添加长而粗的东西的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆