c/c++: float和double、long double

这两天在写程序,看了一些文章,转过来备忘。原文地址是:

http://topic.youkuaiyun.com/u/20090716/10/ce4a7037-3c0d-40ae-af85-f702c78fcea3.html

单精度浮点数在机内占4个字节,用32位二进制描述。
双精度浮点数在机内占8个字节,用64位二进制描述。

浮点数在机内用指数型式表示,分解为:数符,尾数,指数符,指数四部分。
数符占1位二进制,表示数的正负。
指数符占1位二进制,表示指数的正负。
尾数表示浮点数有效数字,0.xxxxxxx,但不存开头的0和点
指数存指数的有效数字。

指数占多少位,尾数占多少位,由计算机系统决定。
可能是数符加尾数占24位,指数符加指数占8位 -- float.
数符加尾数占48位,指数符加指数占16位 -- double.

知道了这四部分的占位,按二进制估计大小范围,再换算为十进制,就是你想知道的数值范围。

对编程人员来说,double 和 float 的区别是double精度高,有效数字16位,float精度7位。但double消耗内存是float的两倍,double的运算速度比float慢得多,C语言中数学函数名称double 和 float不同,不要写错,能用单精度时不要用双精度(以省内存,加快运算速度)。

 

long double标准是规定它是128位浮点数据的,而double是64位浮点数据,但是编译器不一样也有差别,比如vc中它们都是64位的。总之long double >= double =64位是不会错的。 

 

### 关于 C++ `variant` 宏 `index` 参数不足的解决方案 当遇到 C++ 编译器版本为 10.3.1 的情况下,在处理 `<variant>` 头文件中的宏定义时可能出现类似于“参数不足”的错误。这种问题通常源于标准库实现细节与特定编译选项之间的不兼容性。 #### 可能的原因分析 此类错误可能由以下几个方面引起: - **编译器优化级别设置过高**:某些编译器优化可能会干扰模板元编程逻辑,从而导致宏展开失败[^1]。 - **缺少必要的头文件依赖项**:如果项目中未正确引入相关头文件(如 `<type_traits>` 或其他支持类),可能导致宏解析异常。 - **跨平台构建配置差异**:特别是在交叉编译环境中,目标系统的工具链可能存在缺陷或遗漏重要组件[^2]。 #### 推荐解决办法 以下是几种可行的方法来修复该问题: 1. **调整预处理器指令** 尝试修改涉及 `std::variant` 其成员函数的部分代码,确保所有潜在重载都被显式声明出来。例如可以手动指定模板实例化形式如下所示: ```cpp template<typename T> constexpr auto get_index() noexcept { return std::is_same_v<T, int> ? 0 : std::is_same_v<T, double> ? 1 : /* add more types as needed */ -1; } // Usage example within your class definition: decltype(auto) whichType(const QVariant& var){ switch(var.typeId()){ case QMetaType::Int: return get_index<int>(); break; case QMetaType::Double: return get_index<double>();break; default: throw std::runtime_error{"Unsupported type"}; } } ``` 2. **更新 GCC 版本至最新稳定版** 如果当前使用的 GNU Compiler Collection (GCC) 是较旧版本,则建议升级到至少 v11.x.y ,因为更高版本已经修正了许多已知 bug 并改进了 STL 实现一致性. 3. **安装完整的开发环境包组** 对于基于 Debian/Ubuntu Linux 发行版而言,除了基础 build-essential 工具集外还需要额外确认安装了一些辅助性的软件包比如 libmpc-dev、libgomp1 等等。这些对于完全支持现代 C++ 功能至关重要: ```bash sudo apt update && sudo apt full-upgrade -y sudo apt install --no-install-recommends \ gcc-multilib g++-multilib libc6-i386 \ libmpfr-dev libmpc-dev texinfo zlib1g-dev ``` 4. **禁用部分实验特性开关** 部分发行商定制化的 GCC 构建过程中启用了尚未成熟的语言扩展功能,这有时会引发意想不到的行为表现。可以通过命令行传递 `-fno-concepts` 或者类似的标志位关闭对应的功能测试模式尝试绕过此障碍: ```makefile CXXFLAGS += -Wall -Wextra -pedantic-errors \ -O2 -DNDEBUG -march=native \ $(if $(findstring concepts,$(shell echo __GNUC__)),,-fno-constraints) LDFLAGS += -lpthread -lm ``` --- ### 示例代码片段展示如何安全访问 Variant 数据结构 下面提供了一段示范程序说明怎样优雅地操作含有多种不同类型字段的对象集合而不会触发上述提到的那种 runtime exception : ```cpp #include <iostream> #include <variant> #include <vector> #include <memory> using VarData = std::variant< bool, char*, float, long unsigned int>; void processVariant(const VarData &data){ try{ std::visit([](auto&& arg)->decltype(arg){ using T=std::decay_t<decltype(arg)>; if constexpr(std::is_pointer_v<T>) { printf("Pointer value:%s\n", static_cast<char*>(arg)); }else{ cout << typeid(T).name()<<" Value:"<<arg<<'\n'; } return arg; }, data); }catch(...){ cerr<<"Error during visitation.\n"; } } int main(){ vector<std::unique_ptr<VarData>> items={ make_unique<bool>(true), make_unique<char*>((char*)"String Literal"), make_unique<float>(M_PI_4F), make_unique<long unsigned int>(UINTMAX_C(9223372036854775807)) }; for_each(items.begin(),items.end(), [](const unique_ptr<VarData>& ptrItem){ processVariant(*ptrItem);}); return EXIT_SUCCESS; } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值