两个大阶乘相除溢出。急救。

阿博 2004-10-18 04:54:12
我要求一个组合问题。公式为 N! / ( k!*(n-k)! )
当N=292时,并且仅当 k = 132 ...160 时,我的算法走不下去了。
我的算法已经作如下优化处理
(1)分子分母已经约去。如:假设 n-k > k ,则公式变为:
n*(n-1)*(n-2)*...*(n-k+1)
-------------------------
k*(k-1)*(k-2)*...*1
(2)分子分母都把偶数除以2,即: n,n-1,n-2 ... , k,k-1,k-2,... 凡是偶数都先除以2再参与计算。

 发现:当 k=140时,还能有结果。当 k=145,JVM提示:Infinity

 ---- 求求兄弟们帮忙,建议一个好方法 。以下是源码:

public static double zhuhe(int n , int k ){
double N1 = 1d ; // 存放公式中的被除数 N! 约去 max(K!,(N-k)!)后的值。
double N2 = 1d ; // 存放公式中 min(K!,(N-K)!)中的值。
int i_max = Math.max(k,n-k);
int i_min = Math.min(k,n-k);
int i_N1_oushu = 0; // 记录分子(N1)最小值是否偶数。1表示偶数,0表示奇数。
if( (float)i_max/2.0 > Math.round((float)i_max/2.0) ){
i_N1_oushu = 1 ; // i_max是奇数。分子(N1)最小值(i_max+1)是偶数
}
int i_N2_oushu = 0; // 分母肯定是奇数开始,因为从1开始。

int m = 1;
while ( m <= i_min ){
if( i_N1_oushu == 1 ){
N1*=((m+i_max)/2);
i_N1_oushu = 0 ;
}
else {
N1 *= (m + i_max);
i_N1_oushu = 1 ;
}
if( i_N2_oushu == 1) {
N2*=m/2;
i_N2_oushu = 0 ;
}
else{
N2 *= m;
i_N2_oushu = 1 ;
}
m++;
}
return N1/N2;
}
...全文
510 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
阿博 2004-10-19
  • 打赏
  • 举报
回复
我就是在google.com 搜了,找不到有关 浮点。
记得大学时,关于数学的计算,有 MathLab 软件。

--- 现在一搜“高精度计算”,确实有很多。如:超大整数高精度快速计算器

谢谢各位,欢迎继续提供意见。

等我把问题完全解决了,我再来结帐。
过客猫2022 2004-10-19
  • 打赏
  • 举报
回复
数值太大,就不用这个,因为精度有限,网上有大把的例子,介绍高精度计算!
阿博 2004-10-19
  • 打赏
  • 举报
回复
昨晚已经改用BigInteger完成。溢出问题解决了,但是误差问题出来了。

但是结合其它部分的功能求出的概率的总和不为1(或者不接近1)了。
原来采用double时,在100以内的基数进行计算时,概率总和是非常接近1的。

郁闷!!!!!!

谢谢 flyforlove(为情飞)、lee_nan() ,double相乘,也经常出现相当大的误差的,所以,我一直没有采用这种做法。
不过,今天我得试一试。
flyforlove 2004-10-18
  • 打赏
  • 举报
回复
你不应该先求N!然后再计算。应该每项都计算完后再相乘,像lee_nan() ( )所说的那样。

否则本来结果不会溢出,但是在计算过程中却出现了溢出的值,这很不合理。
阿博 2004-10-18
  • 打赏
  • 举报
回复
谢谢。。。正在采用 java.math.BigDecimal 。

---  我马上改用 BigInteger
lee_nan 2004-10-18
  • 打赏
  • 举报
回复
n (n-1) (n-2) (n-k+1)
-* ---- * ---- *..... * ------
k (k-1) (k-2) 1
可否?
追求自由 2004-10-18
  • 打赏
  • 举报
回复
UP
qiyongjun2003 2004-10-18
  • 打赏
  • 举报
回复
用大整型java.math.BigInteger.
内容概要:本文围绕超导磁能储存系统(SMES)的建模与仿真展开,基于Simulink平台构建系统级动态仿真模型,涵盖超导线圈、功率转换系统(PCS)以及核心控制策略等关键模块。研究重点在于分析SMES在电网中实现快速能量存储与释放的能力,验证其在提升电力系统稳定性、抑制功率波动方面的有效性,尤其针对新能源发电带来的间歇性与波动性问题提供了有效的解决方案。通过仿真手段深入探讨系统的动态响应特性,为优化控制算法的设计与应用提供可靠的技术支撑。; 适合人群:适用于具备电力系统、自动控制理论或能源存储技术背景,熟悉Simulink仿真环境的科研人员、工程技术人员及研究生;同时适合有志于开展新型储能技术仿真研究的高年级本科生参考学习。; 使用场景及目标:①深入理解超导磁能储存系统的基本结构、工作原理及其在电力系统中的应用场景;②掌握在Simulink中搭建复杂电力电子与控制系统联合仿真模型的方法;③研究SMES在电网调频、电压支撑、瞬时功率补偿等典型工况下的动态性能表现;④为后续先进控制策略(如PID、模糊控制、现代控制理论等)的优化设计与验证提供仿真试验平台。; 阅读建议:建议读者结合文中模型逐步动手搭建仿真系统,重点关注各功能模块的参数设置与信号接口匹配,配合具体案例进行仿真调试,深入理解控制逻辑与系统动态行为之间的内在联系,并可进一步拓展至与其他储能形式(如锂电池、飞轮储能)的性能对比研究,以深化对不同类型储能技术特点的认知。
内容概要:本文围绕“考虑火-储联合调频(火电机组-混合储能)的协同控制策略”展开研究,提出一种基于Matlab仿真的协同控制方法,旨在提升电力系统频率调节的快速性与稳定性。通过构建火电机组与混合储能(如蓄电池、飞轮等)的联合调频模型,设计合理的功率分配机制与控制策略,充分发挥火电的持续调节能力与储能的快速响应优势,有效应对电网负荷波动与频率偏差。文中结合改进信号分解算法(如ICEEMDAN)与优化算法(如GWO),实现对调频信号的精准分频与储能单元的优化调度,提高系统整体调频效率与经济性。; 适合人群:具备一定电力系统基础知识和Matlab编程能力,从事新能源并网、电力系统稳定控制、储能技术应用等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于研究火电机组与混合储能在电网一次调频、二次调频中的协同作用机制;②为实际电力系统中储能配置与调频控制策略设计提供仿真验证平台与理论支持;③支撑相关课题研究、学术论文撰写及工程项目前期论证。; 阅读建议:建议结合Matlab代码深入理解控制算法实现细节,重点关注功率分配逻辑、信号分解过程与优化算法参数设置,并可通过修改系统参数进行对比仿真,以加深对协同控制效果的认识。

62,622

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧