C++变量类型限制

发布于 2024-08-16 07:45:16 字数 226 浏览 7 评论 0原文

这是一个非常简单的问题(我认为),是否有一个STL库方法提供变量类型的限制 (例如整数) 我知道这些限制在不同的计算机上有所不同,但必须有一种方法可以通过某种方法来实现它们,对吗?

另外,编写一个计算变量类型限制的方法真的很难吗?

我只是很好奇! :)

谢谢 ;)。

here is a quite simple question(I think), is there a STL library method that provides the limit of a variable type (e.g integer) ? I know these limits differ on different computers but there must be a way to get them through a method, right?

Also, would it be really hard to write a method to calculate the limit of a variable type?

I'm just curious! :)

Thanks ;).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

满地尘埃落定 2024-08-23 07:45:16

使用 std::numeric_limits

// numeric_limits example
// from the page I linked
#include <iostream>
#include <limits>
using namespace std;

int main () {
  cout << boolalpha;
  cout << "Minimum value for int: " << numeric_limits<int>::min() << endl;
  cout << "Maximum value for int: " << numeric_limits<int>::max() << endl;
  cout << "int is signed: " << numeric_limits<int>::is_signed << endl;
  cout << "Non-sign bits in int: " << numeric_limits<int>::digits << endl;
  cout << "int has infinity: " << numeric_limits<int>::has_infinity << endl;
  return 0;
}

Use std::numeric_limits:

// numeric_limits example
// from the page I linked
#include <iostream>
#include <limits>
using namespace std;

int main () {
  cout << boolalpha;
  cout << "Minimum value for int: " << numeric_limits<int>::min() << endl;
  cout << "Maximum value for int: " << numeric_limits<int>::max() << endl;
  cout << "int is signed: " << numeric_limits<int>::is_signed << endl;
  cout << "Non-sign bits in int: " << numeric_limits<int>::digits << endl;
  cout << "int has infinity: " << numeric_limits<int>::has_infinity << endl;
  return 0;
}
卷耳 2024-08-23 07:45:16

我看到已经给出了“正确”答案:使用 并让奇迹发生。我碰巧发现这个答案不能令人满意,因为问题是:

编写一个方法来计算变量类型的限制真的很难吗?

答案是:对于整数类型很容易,对于浮点类型很难类型。为此,您需要使用 3 种基本类型的算法。有符号、无符号和浮点数。每个都有不同的算法来获取最小值和最大值,并且实际代码涉及一些位调整,并且在浮点的情况下,您必须循环,除非您有一个与浮点大小相同的已知整数类型类型。

所以,就在这里。

未签名很容易。最小值是当所有位都是 0 时,最大值是当所有位都是 1 时。

const unsigned type unsigned_type_min = (unsigned type)0;    
const unsigned type unsigned_type_max = ~(unsigned type)0;

对于有符号,最小值是当符号位被设置但所有其他位都为零时,最大值是当除符号位之外的所有位都被设置时。如果不知道类型的大小,我们就不知道符号位在哪里,但我们可以使用一些位技巧来使其发挥作用。

const signed type signed_type_max = (signed type)(unsigned_type_max >> 1);
const signed type signed_type_min = (signed type)(~(signed_type_max));

对于浮点,有 4 个限制,尽管只知道正限制就足够了,但负限制只是符号反转的正限制。表示浮点数的方法有很多种,但对于那些使用二进制(而不是基数 10)浮点的方法,几乎​​每个人都使用 IEEE 表示法。

对于 IEEE 浮点数,最小正浮点值是当指数的低位为 1 并且所有其他位为 0 时。最大负浮点值是其按位倒数。但是,如果没有已知与给定浮点类型大小相同的整数类型,则除了执行循环之外没有任何方法可以执行此位操作。如果您知道整数类型与浮点类型大小相同,则可以将其作为单个操作来完成。

const float_type get_float_type_smallest() {
   const float_type float_1 = (float_type)1.0;
   const float_type float_2 = (float_type)0.5;
   union {
      byte ab[sizeof(float_type)];
      float_type fl;
      } u;
   for (int ii = 0; ii < 0; ++ii)
      u.ab[ii] = ((byte*)&float_1)[ii] ^ ((byte*)&float_2)[ii];
   return u.fl;
   }

const float_type get_float_type_largest() {
   union {
      byte ab[sizeof(float_type)];
      float_type fl;
      } u;
   u.fl = get_float_type_smallest();
   for (int ii = 0; ii < 0; ++ii)
      u.ab[ii] = ~u.ab[ii];
   return -u.fl; // Need to re-invert the sign bit.
   }

I see that the 'correct' answer has already been given: Use <limits> and let the magic happen. I happen to find that answer unsatisfying, since the question is:

would it be really hard to write a method to calculate the limit of a variable type?

The answer is : easy for integer types, hard for float types. There are 3 basic types of algorithms you would need to do this. signed, unsigned, and floating point. each has a different algorithm for how you get the min and max, and the actual code involves some bit twiddling, and in the case of floating point, you have to loop unless you have a known integer type that is the same size as the float type.

So, here it is.

Unsigned is easy. the min is when all bits are 0's, the max is when all bits are 1's.

const unsigned type unsigned_type_min = (unsigned type)0;    
const unsigned type unsigned_type_max = ~(unsigned type)0;

For signed, the min is when the sign bit is set but all of the other bits are zeros, the max is when all bits except the sign bit are set. with out knowing the size of the type, we don't know where the sign bit is, but we can use some bit tricks to get this to work.

const signed type signed_type_max = (signed type)(unsigned_type_max >> 1);
const signed type signed_type_min = (signed type)(~(signed_type_max));

for floating point, there are 4 limits, although knowning only the positive limits is sufficient, the negative limits are just sign inverted positive limits. There a potentially many ways to represent floating point numbers, but for those that use binary (rather than base 10) floating point, nearly everyone uses IEEE representations.

For IEEE floats, The smallest positive floating point value is when the low bit of the exponent is 1 and all other bits are 0's. The largest negative floating point value is the bitwise inverse of this. However, without an integer type that is known to be the same size as the given floating point type, there isn't any way to do this bit manipulation other than executing a loop. if you have an integer type that you know is the same size as your floating point type, you can do this as a single operation.

const float_type get_float_type_smallest() {
   const float_type float_1 = (float_type)1.0;
   const float_type float_2 = (float_type)0.5;
   union {
      byte ab[sizeof(float_type)];
      float_type fl;
      } u;
   for (int ii = 0; ii < 0; ++ii)
      u.ab[ii] = ((byte*)&float_1)[ii] ^ ((byte*)&float_2)[ii];
   return u.fl;
   }

const float_type get_float_type_largest() {
   union {
      byte ab[sizeof(float_type)];
      float_type fl;
      } u;
   u.fl = get_float_type_smallest();
   for (int ii = 0; ii < 0; ++ii)
      u.ab[ii] = ~u.ab[ii];
   return -u.fl; // Need to re-invert the sign bit.
   }
动听の歌 2024-08-23 07:45:16

(与C相关,但我认为这也适用于C++)

您也可以尝试“enquire< /a>”,这是一个可以为编译器重新创建 limit.h 的脚本。引自 projetc 主页的一段话:

这个程序决定了很多
C 编译器的属性和
运行它的机器,例如
最小值和最大值 [un]signed
char/int/long,许多属性
float/ [long] double 等等。

作为一个选项,它生成 ANSI C
float.h 和 limit.h 文件。

作为进一步的选项,它甚至检查
编译器读取标头
文件正确。

对于编译器来说这是一个很好的测试用例,
因为它锻炼了他们很多
限制值,例如最小值
和最大浮点数。

(related to C, but I think this also applies for C++)

You can also try "enquire", which is a script which can re-create limits.h for your compiler. A quote from the projetc's home page:

This is a program that determines many
properties of the C compiler and
machine that it is run on, such as
minimum and maximum [un]signed
char/int/long, many properties of
float/ [long] double, and so on.

As an option it produces the ANSI C
float.h and limits.h files.

As a further option, it even checks
that the compiler reads the header
files correctly.

It is a good test-case for compilers,
since it exercises them with many
limiting values, such as the minimum
and maximum floating-point numbers.

ぽ尐不点ル 2024-08-23 07:45:16
#include <limits>

std::numeric_limits<type>::max() // min() etc
#include <limits>

std::numeric_limits<type>::max() // min() etc
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文