组合 __int128

该博客介绍了如何利用__int128类型处理大整数计算,强调了在处理接近1e18的数值时,普通long long可能会导致越界,并解释了越界后的正负情况。通过一道具体题目,展示了__int128在防止计算误差中的重要作用。

原题链接:https://ac.nowcoder.com/acm/contest/1099/B

这道题的关键要点有三个:

1.把公式化简

2.把k变大

即:
 

ll f(ll n,ll k)
{
//k+1 k+2....n
//1 2 3 ...n-k
//if(k<n/2)k=n-k; 
	__int128 ans=1;
	for(ll i=1; i<=n-k; i++)
	{
		ans=ans*(i+k)/i;
		if(ans>1e18)
		{
			return 1e18;
		}
	}
	return ans;
}

公式化简应该没有问题,

把k变大哪怕一开始想不出来,一旦看到第一个测试样例的第一个数据,

应该就会明白了:为了更快的接近1e18

然后还有第三点,即  ans 要用128位整数来表示

稍微解释一下,

在ans快要接近1e18的时候,如果用long long表示ans,下一个数一乘,很有可能越界

然后这个越界并不是说一定就是小于0了,

可能越界完之后是一个正整数,

而且这个正整数可能比越界前小,也可能比越界前大。

所以,__int 128真是个好东西

 

AC代码:

#include<iostream>
#define ll long long
using namespace std;


ll f(ll n,ll k)
{
//k+1 k+2....n
//1 2 3 ...n-k
	__int128 ans=1;
	for(ll i=1; i<=n-k; i++)
	{
		ans=ans*(i+k)/i;
		if(ans>1e18)
		{
			return 1e18;
		}
	}
	return ans;
}


int main()
{

	ll n,k;
	while(cin>>n>>k)
	{
		if(k<n/2)k=n-k; 
		cout<<f(n,k)<<endl;
	}
	return 0;
}

 

<think>嗯,用户想了解Visual Studio中int128的用法或定义。首先,我需要确认Visual Studio是否原生支持128位整数类型。根据已有的知识,C和C++标准中并没有标准的128位整数类型,但一些编译器可能提供扩展支持。比如GCC和Clang有__int128或__int128_t这样的扩展类型。 不过用户提到的是Visual Studio,也就是微软的编译器MSVC。我需要回忆一下MSVC是否支持类似的功能。根据之前了解的信息,MSVC在较旧的版本中并不支持128位整数类型,但可能需要查看最新的文档是否有更新。比如,在Visual Studio 2022或更新的版本中,是否引入了对__int128的支持? 然后,我想到需要检查引用内容是否有相关线索。用户提供的引用中,引用[1]提到Natvis框架用于调试器显示自定义类型,引用[2]是关于Matlab mex函数的创建,引用[3]涉及添加模块定义文件。这些似乎和int128的直接支持无关,但可能间接相关,比如自定义类型显示或跨平台开发时的注意事项。 接下来,可能需要分情况讨论:如果MSVC不支持原生int128,用户有哪些替代方案?比如使用结构体模拟,或者调用编译器内置函数。另外,如果用户需要处理大整数运算,可以使用第三方库如Boost.Multiprecision,或者利用SIMD指令进行部分优化。 还要考虑用户的具体使用场景。比如,是否在需要高性能计算的环境中使用int128,或者进行加密算法开发,这些都可能影响建议的方向。此外,跨平台兼容性也是一个问题,如果用户需要在不同编译器之间移植代码,可能需要使用条件编译或者抽象层来处理不同的实现。 另外,关于调试和显示int128类型,引用[1]提到的Natvis框架可能有用,如果用户自定义了结构体来表示128位整数,可以通过Natvis来优化调试时的显示效果,使其更易读。 最后,需要验证最新的MSVC文档是否支持__int128。可能需要查阅微软的官方文档或更新日志。假设目前MSVC仍未原生支持,那么总结替代方案会是重点。</think>### Visual Studio中int128的定义与使用 Visual Studio(使用MSVC编译器)**不原生支持128位整数类型**(如`__int128`或`int128`),但可以通过以下方法间接实现类似功能: #### 1. 使用结构体模拟128位整数 通过组合两个64位整数实现基本运算: ```cpp struct Int128 { int64_t high; uint64_t low; }; Int128 add(Int128 a, Int128 b) { // 实现加法逻辑(需处理进位) } ``` #### 2. 编译器内置函数(限部分场景) MSVC提供`_umul128`等函数支持部分128位运算: ```cpp uint64_t a = 0xFFFFFFFF; uint64_t b = 0xFFFFFFFF; uint64_t high, low; low = _umul128(a, b, &high); // 计算无符号乘法的高64位和低64位 ``` #### 3. 第三方库 使用Boost.Multiprecision库实现高精度计算: ```cpp #include <boost/multiprecision/cpp_int.hpp> using namespace boost::multiprecision; int128_t x = 12345678901234567890; // 支持128位整数 ``` #### 4. 跨平台兼容性处理 若需兼容GCC/Clang的`__int128`,可使用条件编译: ```cpp #if defined(__GNUC__) || defined(__clang__) typedef __int128 int128_t; #else // 自定义结构体或选择其他方案 #endif ``` --- ### 调试显示优化 若自定义了128位类型,可通过**Natvis框架**[^1]在Visual Studio调试器中增强显示效果: ```xml <AutoVisualizer> <Type Name="Int128"> <DisplayString>{{high=0x{high:X8}, low=0x{low:X8}}}</DisplayString> </Type> </AutoVisualizer> ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值