代码之家  ›  专栏  ›  技术社区  ›  suhair

为什么C中没有数字的基类型?

  •  6
  • suhair  · 技术社区  · 17 年前

    与Java不同的是,为什么C ^没有浮点数、整数等的超级类型?在C中避免数字背后有什么理由吗?

    6 回复  |  直到 17 年前
        1
  •  4
  •   Marc Gravell    17 年前

    我不知道是不是真的,但我听到的一个解释是重量——特别是对于小型框架(紧凑框架、Silverlight、Micro框架);我不相信这一点……

    更令人信服的是 独自一人 知道它是一个数字并不能提供太多;例如,整数除法的工作方式与浮点法非常不同,而且运算符并不总是如您所希望的那样简单(想想 DateTime + TimeSpan => DateTime , DateTime - DateTime => TimeSpan )

    如果有帮助, MiscUtil 提供 generic operator support ,允许如下操作:

    T x = ..., y = ...; // any T that has suitable operators
    T sum = Operator.Add(x,y);
    

    都非常干净有效。但是请注意,没有编译时验证(因为没有合适的通用约束)。但它有效。

        2
  •  6
  •   Joey Gumbo    17 年前

    因为值类型不能被继承。

        3
  •  3
  •   Dario    17 年前

    它可能有 性能原因 -数字,是 struct -类型是堆栈分配的且快速的,但不允许继承结构。以OO方式使用它们需要大量的自动/拆箱,而且由于 更多的内存消耗 和 表查找 解决多态性问题。

    Java已经引入了面向对象的包装器,并结束了不同的和不兼容的实现,对于同一件事情甚至更奇怪。

    为数字提供快速抽象的更好的可能性是引入 打字机 在Haskell或C++中可以编写的概念:

    sum :: (Num t) => [t] -> t
    

    读为 sum接受类型的元素列表 t -其中t是数字类型-并返回这样的数字 .这种机制可以在编译时进行优化,而不需要任何性能开销。但是Net和Java都没有这样的技术。

        4
  •  1
  •   Charles Bretana    17 年前

    但是非常有用的是,如果它们包含了它,那么所有整数类型(int、short、long、uint等)都将被定义为实现一个名为 IIntegral 和所有数值类型(整型加小数型、浮点型等),均已定义为实现名为 INumeric .

    这将允许泛型具有基于这些接口的指定约束,以将允许的类型限制为整型或数值类型,这是当前更困难的问题。

        5
  •  1
  •   BlueMonkMN    17 年前

    ValueType非常接近。没有多少值类型不能表示为单个数字:

      static void Main(string[] args)
      {
         int myInteger = 42;
         decimal myDecimal = 3.141592653589793238M;
         long myLong = 900000000000;
         byte myByte = 128;
         float myFloat = 2.71828F;
    
         TestFunction(myInteger);
         TestFunction(myDecimal);
         TestFunction(myLong);
         TestFunction(myByte);
         TestFunction(myFloat);
      }
    
      static void TestFunction(System.ValueType number)
      {
         Console.WriteLine(number.ToString());
      }
    

    输出:

    • 四十二
    • 3.141592653589793238
    • 九千亿
    • 一百二十八
    • 二点七一八二八
        6
  •  0
  •   Chad Ruppert    17 年前

    您可以创建一个对象的扩展,该对象为您返回一个bool,例如(未测试,可能提供误报等)(捕捉小数、浮点数、整数,使用US样式的十进制分隔符;修改regex以适应十六进制等)

    public static class Object
    {
        static Regex r = new Regex(@"^\d*\.*\d$", RegexOptions.Compiled);
        public static bool IsNumber(this object obj)
        {
            return r.IsMatch(obj.ToString() && !(obj is string);
        }
    }
    

    因为ToString是对象的一部分,而一切最终都是对象的子对象…

    当然,这不会提供类型安全、泛型或其他类似的东西,但是它仍然允许您通过一点更多的工作来做类似的事情。您没有指定基类的用途,无论您是希望在某个地方接受任何数值类型作为参数,还是希望使用泛型。这可能会让你走到你要去的地方。

    用途:

    public class thingThatHasNumericValue
    {
        private object arbNumber;
        public object SomeArbitraryNumber
        {
            get { return arbNumber; }
            set
            {
                if (!arbNumber.IsNumber())
                {
                    throw new InvalidOperationException("Must be a number");
                }
                arbNumber = value;
            }
        }
    }
    
    推荐文章