I have to convert values (double/float in C#) to bytes and need some help..
// Datatype long 4byte -99999999,99 to 99999999,99
// Datatype long 4byte -99999999,9 to 99999999,9
// Datatype short 2byte -999,99 to 999,99
// Datatype short 2byte -999,9 to 999,9
In my "world at home" i would just string it and ASCII.GetBytes().
But now, in this world, we have to make less possible space.
And indeed that '-99999999,99' takes 12 bytes instead of 4! if it's a 'long' datatype.
我必须把值(c#中的双/浮点数)转换成字节,需要一些帮助。//数据类型长4字节- 9999999999,99到999999999999,99 //数据类型长4字节- 99999999999999,9到999999999999999999,9到999999999999999999999999999999,9到999,在我的“在家的世界”我将它串起来。但是现在,在这个世界上,我们必须减少空间的可能性。事实上,“-99999999,99”需要12字节而不是4!如果是“长”数据类型。
[EDIT]
Due to some help and answer I attach some results here,
【编辑】由于一些帮助和答案,我在这里附上一些结果,
long lng = -9999999999L;
byte[] test = Encoding.ASCII.GetBytes(lng.ToString()); // 11 byte
byte[] test2 = BitConverter.GetBytes(lng); // 8 byte
byte[] mybyt = BitConverter.GetBytes(lng); // 8 byte
byte[] bA = BitConverter.GetBytes(lng); // 8 byte
There still have to be one detail left to find out. The lng-variabel got 8 byte even if it helds a lower values, i.e. 99951 (I won't include the ToString() sample).
还需要一个细节才能找到。lng-variabel有8个字节,即使它的值较低,也就是99951(我不包括ToString()示例)。
If the value are even "shorter", which means -999,99 -- 999,99 it will only take 2 byte space.
[END EDIT]
如果值更“短”,也就是-999,99 -999,99只需要2字节的空间。(结束编辑)
5 个解决方案
#1
5
Be aware that in 2 bytes you can only have 4 full digits + sign, and in 4 bytes you can only have 9 digits + sign, so I had to scale your prereqs accordingly.
请注意,在2个字节中,您只能有4个完整数字+符号,在4个字节中,您只能有9个数字+符号,因此我必须相应地扩展您的预判。
public static byte[] SerializeLong2Dec(double value)
{
value *= 100;
value = Math.Round(value, MidpointRounding.AwayFromZero);
if (value < -999999999.0 || value > 999999999.0)
{
throw new ArgumentOutOfRangeException();
}
int value2 = (int)value;
return BitConverter.GetBytes(value2);
}
public static double DeserializeLong2Dec(byte[] value)
{
int value2 = BitConverter.ToInt32(value, 0);
return (double)value2 / 100.0;
}
public static byte[] SerializeLong1Dec(double value) {
value *= 10;
value = Math.Round(value, MidpointRounding.AwayFromZero);
if (value < -999999999.0 || value > 999999999.0) {
throw new ArgumentOutOfRangeException();
}
int value2 = (int)value;
return BitConverter.GetBytes(value2);
}
public static double DeserializeLong1Dec(byte[] value) {
int value2 = BitConverter.ToInt32(value, 0);
return (double)value2 / 10.0;
}
public static byte[] SerializeShort2Dec(double value) {
value *= 100;
value = Math.Round(value, MidpointRounding.AwayFromZero);
if (value < -9999.0 || value > 9999.0) {
throw new ArgumentOutOfRangeException();
}
short value2 = (short)value;
return BitConverter.GetBytes(value2);
}
public static double DeserializeShort2Dec(byte[] value) {
short value2 = BitConverter.ToInt16(value, 0);
return (double)value2 / 100.0;
}
public static byte[] SerializeShort1Dec(double value) {
value *= 10;
value = Math.Round(value, MidpointRounding.AwayFromZero);
if (value < -9999.0 || value > 9999.0) {
throw new ArgumentOutOfRangeException();
}
short value2 = (short)value;
return BitConverter.GetBytes(value2);
}
public static double DeserializeShort1Dec(byte[] value) {
short value2 = BitConverter.ToInt16(value, 0);
return (double)value2 / 10.0;
}
So that it's clear, the range of a (signed) short (16 bits) is -32,768 to 32,767 so it's quite clear that you only have 4 full digits plus a little piece (the 0-3), the range of a (signed) int (32 bits) is −2,147,483,648 to 2,147,483,647 so it's quite clear that you only have 9 full digits plus a little piece (the 0-2). Going to a (signed) long (64 bits) you have -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 so 18 digits plus a (big) piece. Using floating points you lose in accuracy. A float (32 bits) has an accuracy of around 7 digits, while a double (64 bits) has an accuracy of around 15-16 digits.
所以很明显,(签署)短的范围(16位)是-32768年到32767年,所以很明显,你只有4全数字加一小段(0 - 3)的范围(签署)int(32位)−2147483648年至2147483647年,那么很明显,你只有9位数加上一小段(0 - 2)。到a(签名)长(64位)你有-9,223,372,036,854,775,808到9,223,372,036,854,775,807,所以18位数字加一个(大)块。使用浮点数会降低准确度。浮点数(32位)的精度约为7位,双精度数(64位)的精度约为15-16位。
#2
15
Have you checked BitConverter
你检查BitConverter
long lng =-9999999999L;
byte[] mybyt = BitConverter.GetBytes(lng);
hope this is what you are looking
希望这是你所看到的。
#3
5
Try to do it in this way:
试着这样做:
long l = 4554334;
byte[] bA = BitConverter.GetBytes(l);
#4
1
long longValue = 9999999999L;
Console.WriteLine("Long value: " + longValue.ToString());
bytes = BitConverter.GetBytes(longValue);
Console.WriteLine("Byte array value:");
Console.WriteLine(BitConverter.ToString(bytes));
#5
1
As the other answers have pointed out, you can use BitConverter
to get the byte representation of primitive types.
正如其他答案所指出的,您可以使用位转换器来获得原始类型的字节表示。
You said that in the current world you inhabit, there is an onus on representing these values as concisely as possible, in which case you should consider variable length encoding (though that document may be a bit abstract).
您说过,在当前的环境中,您需要尽可能简洁地表示这些值,在这种情况下,您应该考虑可变长度编码(尽管该文档可能有点抽象)。
If you decide this approach is applicable to your case I would suggest looking at how the Protocol Buffers project represents scalar types as some of these types are encoded using variable length encoding which produces shorter output if the data set favours smaller absolute values. (The project is open source under a New BSD license, so you will be able to learn the technique employed from the source repository or even use the source in your own project.)
如果您认为这种方法适用于您的情况,我建议您看看协议缓冲区项目是如何表示标量类型的,因为其中一些类型是使用可变长度编码进行编码的,如果数据集偏爱更小的绝对值,那么这些编码将产生更短的输出。(根据新的BSD许可证,该项目是开源的,因此您将能够从源存储库中学习使用的技术,甚至可以在您自己的项目中使用源。)
#1
5
Be aware that in 2 bytes you can only have 4 full digits + sign, and in 4 bytes you can only have 9 digits + sign, so I had to scale your prereqs accordingly.
请注意,在2个字节中,您只能有4个完整数字+符号,在4个字节中,您只能有9个数字+符号,因此我必须相应地扩展您的预判。
public static byte[] SerializeLong2Dec(double value)
{
value *= 100;
value = Math.Round(value, MidpointRounding.AwayFromZero);
if (value < -999999999.0 || value > 999999999.0)
{
throw new ArgumentOutOfRangeException();
}
int value2 = (int)value;
return BitConverter.GetBytes(value2);
}
public static double DeserializeLong2Dec(byte[] value)
{
int value2 = BitConverter.ToInt32(value, 0);
return (double)value2 / 100.0;
}
public static byte[] SerializeLong1Dec(double value) {
value *= 10;
value = Math.Round(value, MidpointRounding.AwayFromZero);
if (value < -999999999.0 || value > 999999999.0) {
throw new ArgumentOutOfRangeException();
}
int value2 = (int)value;
return BitConverter.GetBytes(value2);
}
public static double DeserializeLong1Dec(byte[] value) {
int value2 = BitConverter.ToInt32(value, 0);
return (double)value2 / 10.0;
}
public static byte[] SerializeShort2Dec(double value) {
value *= 100;
value = Math.Round(value, MidpointRounding.AwayFromZero);
if (value < -9999.0 || value > 9999.0) {
throw new ArgumentOutOfRangeException();
}
short value2 = (short)value;
return BitConverter.GetBytes(value2);
}
public static double DeserializeShort2Dec(byte[] value) {
short value2 = BitConverter.ToInt16(value, 0);
return (double)value2 / 100.0;
}
public static byte[] SerializeShort1Dec(double value) {
value *= 10;
value = Math.Round(value, MidpointRounding.AwayFromZero);
if (value < -9999.0 || value > 9999.0) {
throw new ArgumentOutOfRangeException();
}
short value2 = (short)value;
return BitConverter.GetBytes(value2);
}
public static double DeserializeShort1Dec(byte[] value) {
short value2 = BitConverter.ToInt16(value, 0);
return (double)value2 / 10.0;
}
So that it's clear, the range of a (signed) short (16 bits) is -32,768 to 32,767 so it's quite clear that you only have 4 full digits plus a little piece (the 0-3), the range of a (signed) int (32 bits) is −2,147,483,648 to 2,147,483,647 so it's quite clear that you only have 9 full digits plus a little piece (the 0-2). Going to a (signed) long (64 bits) you have -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 so 18 digits plus a (big) piece. Using floating points you lose in accuracy. A float (32 bits) has an accuracy of around 7 digits, while a double (64 bits) has an accuracy of around 15-16 digits.
所以很明显,(签署)短的范围(16位)是-32768年到32767年,所以很明显,你只有4全数字加一小段(0 - 3)的范围(签署)int(32位)−2147483648年至2147483647年,那么很明显,你只有9位数加上一小段(0 - 2)。到a(签名)长(64位)你有-9,223,372,036,854,775,808到9,223,372,036,854,775,807,所以18位数字加一个(大)块。使用浮点数会降低准确度。浮点数(32位)的精度约为7位,双精度数(64位)的精度约为15-16位。
#2
15
Have you checked BitConverter
你检查BitConverter
long lng =-9999999999L;
byte[] mybyt = BitConverter.GetBytes(lng);
hope this is what you are looking
希望这是你所看到的。
#3
5
Try to do it in this way:
试着这样做:
long l = 4554334;
byte[] bA = BitConverter.GetBytes(l);
#4
1
long longValue = 9999999999L;
Console.WriteLine("Long value: " + longValue.ToString());
bytes = BitConverter.GetBytes(longValue);
Console.WriteLine("Byte array value:");
Console.WriteLine(BitConverter.ToString(bytes));
#5
1
As the other answers have pointed out, you can use BitConverter
to get the byte representation of primitive types.
正如其他答案所指出的,您可以使用位转换器来获得原始类型的字节表示。
You said that in the current world you inhabit, there is an onus on representing these values as concisely as possible, in which case you should consider variable length encoding (though that document may be a bit abstract).
您说过,在当前的环境中,您需要尽可能简洁地表示这些值,在这种情况下,您应该考虑可变长度编码(尽管该文档可能有点抽象)。
If you decide this approach is applicable to your case I would suggest looking at how the Protocol Buffers project represents scalar types as some of these types are encoded using variable length encoding which produces shorter output if the data set favours smaller absolute values. (The project is open source under a New BSD license, so you will be able to learn the technique employed from the source repository or even use the source in your own project.)
如果您认为这种方法适用于您的情况,我建议您看看协议缓冲区项目是如何表示标量类型的,因为其中一些类型是使用可变长度编码进行编码的,如果数据集偏爱更小的绝对值,那么这些编码将产生更短的输出。(根据新的BSD许可证,该项目是开源的,因此您将能够从源存储库中学习使用的技术,甚至可以在您自己的项目中使用源。)