C# 中基本数值类型之间的计算类型是什么?

  • 使用 int 和 long 进行计算会导致 long
  • 使用 int 和 double 进行计算会产生 double

我相信你已经听说过很多了,但是在 C# 或 .NET 中,有许多类型的数值,哪一种会被计算,哪一种呢?这是一个备忘录。

计算

sbyte sbyteL = 0, sbyteR = 0;
byte byteL = 0, byteR = 0;
...
char charL = '0', charR = '0';

Console.WriteLine("sbyte + sbyte -> {0}", (sbyteL + sbyteR).GetType());
Console.WriteLine("sbyte + byte -> {0}", (sbyteL + byteR).GetType());
...
Console.WriteLine("char + char -> {0}", (charL + charR).GetType());

这样做的结果如下。

我正在运行 Visual Studio 2022.NET 6.0 并排除明显不是数字或没有小写别名的类型。

大小,有符号或无符号

左右字节字节短的超短字符整数单位乌龙漂浮双倍的十进制
字节整数整数整数整数整数整数CS0034漂浮双倍的十进制
字节整数整数整数整数整数整数单位乌龙漂浮双倍的十进制
短的整数整数整数整数整数整数CS0034漂浮双倍的十进制
超短整数整数整数整数整数整数单位乌龙漂浮双倍的十进制
字符整数整数整数整数整数整数单位乌龙漂浮双倍的十进制
整数整数整数整数整数整数整数CS0034漂浮双倍的十进制
单位单位单位单位单位乌龙漂浮双倍的十进制
CS0034漂浮双倍的十进制
乌龙CS0034乌龙CS0034乌龙乌龙CS0034乌龙CS0034乌龙漂浮双倍的十进制
漂浮漂浮漂浮漂浮漂浮漂浮漂浮漂浮漂浮漂浮漂浮双倍的CS0019
双倍的双倍的双倍的双倍的双倍的双倍的双倍的双倍的双倍的双倍的双倍的双倍的CS0019
十进制十进制十进制十进制十进制十进制十进制十进制十进制十进制CS0019CS0019十进制

签名/未签名,尺寸顺序

左右字节短的整数字节超短字符单位乌龙漂浮双倍的十进制
字节整数整数整数整数整数整数CS0034漂浮双倍的十进制
短的整数整数整数整数整数整数CS0034漂浮双倍的十进制
整数整数整数整数整数整数整数CS0034漂浮双倍的十进制
CS0034漂浮双倍的十进制
字节整数整数整数整数整数整数单位乌龙漂浮双倍的十进制
超短整数整数整数整数整数整数单位乌龙漂浮双倍的十进制
字符整数整数整数整数整数整数单位乌龙漂浮双倍的十进制
单位单位单位单位单位乌龙漂浮双倍的十进制
乌龙CS0034CS0034CS0034CS0034乌龙乌龙乌龙乌龙乌龙漂浮双倍的十进制
漂浮漂浮漂浮漂浮漂浮漂浮漂浮漂浮漂浮漂浮漂浮双倍的CS0019
双倍的双倍的双倍的双倍的双倍的双倍的双倍的双倍的双倍的双倍的双倍的双倍的CS0019
十进制十进制十进制十进制十进制十进制十进制十进制十进制十进制CS0019CS0019十进制

错误

代码意义
CS0034'type1' 和 'type2' 类型的操作数的模棱两可的运算符 'operator'
CS0019运算符“运算符”不能应用于“类型”和“类型”类型的操作数

概括

  • 整数到整数
    • 16 位整数或整数的任意组合变为整数
    • 32 位或更多无符号整数 + 有符号整数变为有符号整数,比无符号整数大一
      • uint + 有符号整数变长
      • ulong + 有符号整数给出 CS0034 错误(因为基础类型没有大于 ulong 的有符号整数?)
    • 32 位或更多无符号整数 + 无符号整数更大
      • uint + 32 位或更少的无符号整数变为 uint
      • ulong + 无符号整数变为 ulong
    • long + ulong 以外的整数变为 long
  • 整数和小数
    • 整数 + 小数到小数
  • 小数和小数
    • 十进制 + IEEE754 导致 CS0019 错误
    • IEEE754组合更大
      • float + double 变为 double

[CLSCompliant(true)]

  • 整数到整数
    • int 以下的组合变为 int
    • 与 long 组合导致 long
  • 整数和小数
    • 整数 + 小数到小数
  • 小数和小数
    • 十进制 + IEEE754 导致 CS0019 错误
    • IEEE754组合更大
      • float + double 变为 double

会很简单,ulong或者CLSCompliant(false),所以不会用到CS0034。

我制作这张桌子的原因是

@987654324 在设置为不可用的类库上,T 型值 T from to T to 由 V 型值 V 步进(基本假设 V = T)@ 我想创建类似@987654327 的东西@在987654326@接口实现类中

  • 如果 V step 是数值类型中等价于 1 的值,则如果存在自增运算符,则自增运算符
  • 如果 V step 是数值类型中等价于 -1 的值,则如果存在减量运算符,则减量运算符
  • 加法运算符,如果 V 步不是上述或没有相应的增量或减量运算符

如果你准备一个技巧,看看你是否可以通过拾取反射来实现运算符重载

  • 无法从大多数具有小写别名的类型中获取运算符重载,这应该非常有用(似乎正在努力使用专用机制)
  • 带运算符重载的小数只准备用于带小数的计算(似乎他们通过查看隐式正在尽最大努力)
  • 如果在对象类型变量中存储一个int类型的值并设置为(long),会与类型不匹配,但是会报错,所以需要正确返回后进行强制转换。
    • 小写类型实现基本的IConvertible 接口并具有ToXXX() 方法,转换.ChangeType(object, Type)可以匹配任何一种类型,因此您所要做的就是创建一个转换表,告诉您当您有两种类型时要匹配哪个

结果是这样的,所以我为不同类型的计算做了一个对应表。

我也在做类似你的事情,你想用一种允许你自由地进行二进制操作的强类型语言来做什么。

如果你可以使用dynamic,你可以很容易地在这里写,但是由于各种原因你不能将它用于你现在正在制作的部分,所以我在实现它时没有改进。 (即使可以使用,运行时出现CS0034和CS0019的地方也会报错)

原创声明:本文系作者授权爱码网发表,未经许可,不得转载;

原文地址:https://www.likecs.com/show-308632905.html