RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 887038
Accepted
Kir_Antipov
Kir_Antipov
Asked:2020-09-30 00:03:13 +0000 UTC2020-09-30 00:03:13 +0000 UTC 2020-09-30 00:03:13 +0000 UTC

指定结构位域的大小

  • 772

为了方便使用System.Double ( float64) 类型的数字,我想描述一个类似的结构:

// cpp code
union float64
{
    double x;
    struct
    {
        unsigned long long mant : 52;
        unsigned long long exp  : 11;
        unsigned long long sign : 1;
    };

    float64(double val) { x = val; }
};

float64 f = -4.0;
// f.mant == 0
// f.exp == 1025 (- 1023 == 2)
// f.sign == 1

换句话说,我需要由IEC 60559:1989 (IEEE 754) 标准描述的浮点数的底线,可以快速访问

这C++很容易用位域来表示。但是C#,我无法弄清楚如何(优雅地)执行此操作:MarshalAsAttribute.SizeConst的使用仅对字符串和数组有效

所以到目前为止我看到的唯一选择是使用fixed-fields,然后我需要的数字将从中加载。但是这个解决方案对我来说似乎有点麻烦......


是否可以使用 C# 指定特定大小的位域,如果可以,如何执行此操作?

c#
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Qwertiy
    2020-09-30T01:37:05Z2020-09-30T01:37:05Z

    https://ideone.com/wGW2qq

    using System;
    using System.Runtime.InteropServices;
    
    [StructLayout(LayoutKind.Explicit)]
    struct Float64
    {
      public Float64(double x) { ULong = 0; Double = x; }
      public static implicit operator Float64(double x) { return new Float64(x); }
      public static implicit operator double(Float64 x) { return x.Double; }
    
      [FieldOffset(0)] public double Double;
      [FieldOffset(0)] public ulong  ULong;
    
      public ulong Mantissa
      {
        get { return ULong & 0xFFFFFFFFFFFFF; }
        set { ULong = ULong & ~0xFFFFFFFFFFFFFULL | value & 0xFFFFFFFFFFFFFULL; }
      }
    
      public uint Exp
      {
        get { return (uint)((ULong >> 52) & 0x7FF); }
        set { ULong = ULong & 0x800FFFFFFFFFFFFFULL | ((ulong)(value & 0x7FF) << 52); }
      }
    
      public uint Sign
      {
        get { return (uint)(ULong >> 63); }
        set { ULong = ULong & 0x7FFFFFFFFFFFFFFFULL | ((ulong)value << 63); }
      }
    }
    
    public class Test
    {
      private static void Print(Float64 x)
      {
        Console.WriteLine("{0,7} {1:X16} s={4} m={2:X13} e={3:X3}", x.Double, x.ULong, x.Mantissa, x.Exp, x.Sign);
      }
    
      public static void Main()
      {
        foreach (var d in new double [] { 0,1,-1,2,-2,3,-3,3.25,-3.25 })
          Print(d);
    
        Float64 x = 1;
        Print(x);
        ++x.Exp; Print(x); // 2
        x.Sign = 1; Print(x); // -2
        x.Mantissa += 1ULL << 51; Print(x); // -3
        --x.Exp; Print(x); // -1.5
      }
    }
    
          0 0000000000000000 s=0 m=0000000000000 e=000
          1 3FF0000000000000 s=0 m=0000000000000 e=3FF
         -1 BFF0000000000000 s=1 m=0000000000000 e=3FF
          2 4000000000000000 s=0 m=0000000000000 e=400
         -2 C000000000000000 s=1 m=0000000000000 e=400
          3 4008000000000000 s=0 m=8000000000000 e=400
         -3 C008000000000000 s=1 m=8000000000000 e=400
       3.25 400A000000000000 s=0 m=A000000000000 e=400
      -3.25 C00A000000000000 s=1 m=A000000000000 e=400
          1 3FF0000000000000 s=0 m=0000000000000 e=3FF
          2 4000000000000000 s=0 m=0000000000000 e=400
         -2 C000000000000000 s=1 m=0000000000000 e=400
         -3 C008000000000000 s=1 m=8000000000000 e=400
       -1.5 BFF8000000000000 s=1 m=8000000000000 e=3FF
    
    • 8
  2. VladD
    2020-09-30T02:57:26Z2020-09-30T02:57:26Z

    另一个允许您在不安全的情况下进行操作的选项[StructLayout(LayoutKind.Explicit)]是:

    struct Float64
    {
        public Float64(double x) { Double = x; }
        public static implicit operator Float64(double x) { return new Float64(x); }
        public static implicit operator double(Float64 x) { return x.Double; }
    
        public double Double;
        public ulong ULong
        {
            get => (ulong)BitConverter.DoubleToInt64Bits(Double);
            set => Double = BitConverter.Int64BitsToDouble((long)value);
        }
    
        ...
    }
    

    其余代码与@Qwertiy 的答案相同。

    • 6

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5