看看这个C#代码:
byte x = 1;
byte y = 2;
byte z = x + y; // ERROR: Cannot implicitly convert type 'int' to 'byte'
Run Code Online (Sandbox Code Playgroud)
对byte(或short)类型执行的任何数学运算的结果都隐式地转换回整数.解决方案是将结果显式地转换回一个字节:
byte z = (byte)(x + y); // this works
Run Code Online (Sandbox Code Playgroud)
我想知道的是为什么?它是建筑吗?哲学?
我们有:
int+ int=intlong+ long=longfloat+ float=floatdouble+ double=double那么为什么不呢:
byte+ byte=byteshort+ short= short?一点背景:我正在对"小数字"(即<8)执行一长串计算,并将中间结果存储在一个大数组中.使用字节数组(而不是int数组)更快(因为缓存命中).但是通过代码传播的大量字节转换使得它更加难以理解.
我编写了以下小程序来打印出Fibonacci序列:
static void Main(string[] args)
{
Console.Write("Please give a value for n:");
Int16 n = Int16.Parse(Console.ReadLine());
Int16 firstNo = 0;
Int16 secondNo = 1;
Console.WriteLine(firstNo);
Console.WriteLine(secondNo);
for (Int16 i = 0; i < n; i++)
{
//Problem on this line
Int16 answer = firstNo + secondNo;
Console.WriteLine(answer);
firstNo = secondNo;
secondNo = answer;
}
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
编译消息是:
无法将类型'int'隐式转换为'short'.存在显式转换(您是否错过了演员?)
由于涉及的所有内容都是Int16(简称),那么为什么会有任何隐式转换?更具体地说,为什么在这里失败(而不是最初为变量赋予int)?
非常感谢您的解释.
发现一个有趣的问题,以下代码运行时具有不同的结果:
char c = 'a';
c += 'a'; //passed
c = c + 'a'; //Cannot implicitly convert type 'int' to 'char'. An explicit conversion exists (are you missing a cast?)
Run Code Online (Sandbox Code Playgroud)
有什么区别a += b和a=a+b,或只是编译器的代码检查错过呢?
我的观点是为什么char += char在char = (char+char)考虑时可以通过代码检查char = int?
为什么是
byte someVar;
someVar -= 3;
Run Code Online (Sandbox Code Playgroud)
有效但是
byte someVar;
someVar = someVar - 3;
Run Code Online (Sandbox Code Playgroud)
心不是?
以前我今天尝试添加两个ushorts,我注意到我必须将结果反馈给ushort.我认为它可能会成为一个uint(以防止可能的意外溢出?),但令我惊讶的是它是一个int(System.Int32).
是否有一些聪明的理由或者是因为int被视为'基本'整数类型?
例:
ushort a = 1;
ushort b = 2;
ushort c = a + b; // <- "Cannot implicitly convert type 'int' to 'ushort'. An explicit conversion exists (are you missing a cast?)"
uint d = a + b; // <- "Cannot implicitly convert type 'int' to 'uint'. An explicit conversion exists (are you missing a cast?)"
int e = a + b; // <- Works!
Run Code Online (Sandbox Code Playgroud)
编辑:就像GregS的回答所说,C#规范说两个操作数(在这个例子中是'a'和'b')应该转换为int.我对为什么这是规范的一部分的根本原因感兴趣:为什么C#规范不允许直接对ushort值进行操作?
我的问题基本上是关于C#编译器如何处理小数据类型的内存分配.我知道例如像add这样的运算符是在int上定义的而不是在short上定义的,因此计算将被执行,好像short是int成员一样.
假设如下:
是否尽可能使用短数据类型会减少应用程序的内存占用量,是否建议这样做?或者使用short等不值得花费,因为编译器例如分配int32的完整内存ammount并在进行算术时添加额外的强制转换.
任何关于假定的运行时性能影响的链接都将非常感激.
相关问题:
在高级别SO用户的建议下,我最近开始使用-Wconversion我的代码库上的标志进行编译.这产生了很多警告,其中一些是合法的(例如,不必要的添加signed和unsigned类型),但也有一些头部刮擦,如下所示:
#include <cstdint>
int main()
{
uint16_t a = 4;
uint16_t b = 5;
b += a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我编译时g++ -Wconversion -std=c++11 -O0 myFile.cpp,我得到了
warning: conversion to 'uint16_t {aka short unsigned int}' from 'int' may alter its value [-Wconversion]
b += a;
^
Run Code Online (Sandbox Code Playgroud)
我细读上SO(处理一些类似的问题|和<<运营商),采取一看这里,并已阅读了数字升级和数值转换部分在这里.我的理解是,为了进行数学计算,a并b被提升为int(因为这是第一种可以适应整个uint16_t值范围的类型),执行数学运算,结果被写回...除了数学结果是一个int并写回来uint16_t生成警告.其他问题的共识基本上是抛弃了警告,而我唯一能想出如何做到这一点的方法就是b = (uint16_t)(b + a);(或等价的b …
我有一个代码:
static short Sum(short a, short b)
{
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
而且它没有编译,saynig无法将'int'转换为'short'.我今天可能真的很累,但我看不出这个问题!
您将如何在字节,短路和无符号值的集合上使用LINQ聚合函数(例如Sum,Average)?当然,我是一个新的C#程序员,但我甚至无法弄清楚如何获得编译的东西,更不用说有适当的输出了.
这是我想要做的一个简单的例子:
short[] numbersArray = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
short sumArray = numbersArray.Sum();
Run Code Online (Sandbox Code Playgroud)
要么
List<short> numbersList = new List<short> { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
short sumList = numbersList.Sum();
Run Code Online (Sandbox Code Playgroud)
我无法使用这些样本中的任何一个.如果我将数据类型更改为int它可以工作,但我不能让它适用于short,bytes,uints等.
我究竟做错了什么?
short BitwiseTest(short value)
{
short test1 = ((value >> 8) & 0xFF);
short test2 = unchecked((short)((value << 8) & 0xFF00));
return (test1 | test2);
}
Run Code Online (Sandbox Code Playgroud)
上面的代码应该是一个(低效)示例,它在C#中交换短(带符号的16位整数)的字节序.
但是上面的代码不会编译,因为C#在以下两行中隐式地从short转换为int:
第一种情况:
short test1 = ((value >> 8) & 0xFF);
Run Code Online (Sandbox Code Playgroud)
第二种情况:
return (test1 | test2);
Run Code Online (Sandbox Code Playgroud)
为什么要进行演员表演?我是否可以通过简短的回归来实现预期的结果?像这样:
short BitwiseTest2(short value)
{
short test1 = (short)((value >> 8) & 0xFF);
short test2 = unchecked((short)((value << 8) & 0xFF00));
return ((short)(test1 | test2));
}
Run Code Online (Sandbox Code Playgroud)
如果不是为什么不呢?
请注意,我确实理解为什么C#在执行左位移时将短路转换为整数,因此分配了test2变量.