javamath类
A. 在java中什么意思 Math.abs(x)及同类的的公式
该方法返回x的绝对值,x的取值可以是各种类型参数。
Math.abs(x)=|x|;如果参数是非负数,则返回该参数。如果参数是负数,则返回该参数的相反数。
特殊情况是:
如果参数是正零或负零,那么结果是正零。
如果参数是无穷大,那么结果是正无穷大。
如果参数是 NaN,那么结果就是 NaN。
NAN:
NaN,是Not a Number的缩写。
NaN 用于处理计算中出现的错误情况,比如 0.0 除以 0.0 或者求负数的平方根。对于单精度浮点数,NaN 表示为指数为 emax + 1 = 128(指数域全为 1),且尾数域不等于零的浮点数。
EEE 标准没有要求具体的尾数域,所以 NaN 实际上不是一个,而是一族。不同的实现可以自由选择尾数域的值来表达 NaN。
比如 Java 中的常量 Float.NaN 的浮点数可能表达为 011111111100000000000000,其中尾数域的第一位为 1,其余均为 0(不计隐藏的一位)。
但这取决系统的硬件架构。Java 中甚至允许程序员自己构造具有特定位模式的 NaN 值(通过 Float.intBitsToFloat() 方法)。
比如,程序员可以利用这种定制的 NaN 值中的特定位模式来表达某些诊断信息。
(1)javamath类扩展阅读
java中math提供用于执行任意精度整数算法 和任意精度小数算法 的类。
同类公式:
java Math类常用的方法:
圆周率:Math.PI
自然对数:Math.E
绝对值:Math.abs
向上取整数:Math.ceil;
向下取整数:Math.floor;
B. java中Math类中的random方法和Random类有什么区别
random方法是java.lang.Math的方法,作用是返回带正号的 double 值,该值搭逗大于等于 0.0 且小于 1.0。而Random类是一个类(java.util.Random),里面含有很多方法。
Math.random()返回的只是从0到1之间的小数,如果要50到100,就先知局卖放大50倍,即0到50之间,这里还是小数,如果要整数,就强制转换int,然后再加上50即为50~100。最终代码:(int)(Math.random()*50) + 50。
Random类产生的随机数,在其最大值范围内,按照概率均匀分布的。也就是说,两个种子数相同的Random对象,第一次生成的腊枣随机数字完全相同,第二次生成的随机数字也完全相同。
C. JAVA俩类,用类的时候为什么Math类不需要new 呢
1.StringBuffer为羡丛激什么要new?
答:java是面向对象语言,简单的来说,就是化执行者为指挥者。而类的对象就是通过new关郑歼键字来创建对象的,再通过对象来引用成员变量和成员方法,这个深层的原因:和java在编译期对new转化的虚拟机指令有关系。这个不多说。
2.Math类为什么不需要new?
答:Math是JDK提供的一个工具类,1.6版本的申明源码如下:
兄袜publicfinalclassMath{
/**
*Don'.
*/
privateMath(){}
如上面源码所示, 构造器私有化,所以无法创建对象,这就好比你使用单例模式,就需要私有化构造器来防止其他的人创建对象。再看方法:
publicstaticintabs(inta){
return(a<0)?-a:a;
}
源码中的方法都是静态方法,所以,这部分静态的方法在类加载的时候已经在方法区中申明出来了,不回参与你的对象实例化的过程,和对象创建没有关系。所以,静态的方法都是通过类型直接引用的,和你创不创建对象没有关系。这就是我为什么在上面写成员方法,为了和这里的静态方法区分开。
D. Java中怎样调用Math中的方法
Math类中的方法一般都为静态方法,直接使用类名.方法名(实参列表)即可调用,如调用Math中的max函数的语句为Math.max(3, 5);其返回3,5中较大的值。
Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数等,Math类在包java.lang中,是默认导入的包,使用时不需要额外导入包。。
E. java Math类中的pow方法
Math.pow(64,1/3)等价于 Math.pow(64,0)所以结果是1.0
在程序中 1/3并不代表三分之一,因为这里是两个int类型在做除法,结果也是int类型,会自动取整(向下取0了), 所以是0,就可以说明为什么结果是1。执行代码如下
System.out.println(1/3)
运行结果
这里1.0/3.0近似等于0.3333333333所以,最后结果为上图所示。
拓展知识
1.0做除数抛运行时异常;两整数商会做取整运算,Float或Double与一个整数做除法运算,则商位Float或者Double类型
2.0可以做除数,得到的是一个分正负的无穷大;当两个数的绝对值均为0.0时候,商等于NaN。当0.0/x,x不等0.0时候
F. Java中的Math函数
new Random()就是一个随即数对象,然后nextInt为获取当前随机数对象的随即产生的一个整数,%100就是用这个整数对100求模,获得其余(该余在-99 至 99之间),Math.abs为取绝对值,再加1,则获得[1, 100]之间的整数,包括1,100
G. java中的java.math包是什么
是数学函数相关的方法,比如开平方,几次方,求平均数等
H. 求解java中Math类中的取整方法
public static long round(double a)
返回最接近参数的 long 长整型。结果将四舍五入为整数,对结果调用 Math.floor函数, 并将所得结果强制转换为 long 类型。
换句话说,结果等于以下表达式的值:
(long)Math.floor(a + 0.5d)
对于负数的四舍五入规则是 先把负数转换为正数,四舍五入后,再转换为负数
-2.6转换为正数2.6,四舍五入2.6+0.5=3.1,然后再转为负数-3.1
用Math.floor函数去掉小数部分为-3,然后强制转换成长整型-3.
-2.4转换为正数2.4,四舍五入2.4+0.5=2.9,然后再转为负数-2.9
用Math.floor函数去掉小数部分为-2,然后强制转换成长整型-2.
所以Math.round(-2.6)=-3,Math.round(-2.4)=-2.
I. java中Math提供的是哪个取整的方法
Math类中提供的三个与取整有关的方法:
第一个: ceil
ceil的意思就是: 天花板的意思;该方法表示的是向上取整Math.ceil(11.3)的值是12 ; Math.ceil.(-11.6)的结果是-11;
第二个是: floor
首先他的英文含义就是地板的含义,该方法就表示的是向下取整,
Math.floor(11.6)的结果就是11 ;
Math.floor(-11.4);的结果就是-12
第三个是: round
他表示的是四舍五入,算法为 Math.floor(x+0.5);也就是在原来的数字上加上0.5之后再进行向下取整;
Math.round(11.5);也就是 Math.floor(11.5+0.5)= Math.floor(12)=12;
同理: Math.round(-11.5)= Math.floor(-11.5+0.5)=Math.floor(-11.0)= -11;
J. Java Math类中的新功能,第1 部分:实数
摘要 在这篇由两部分组成的仔弊文章中 Elliotte Rusty Harold 与您一起探讨经典 java lang Math 类中的 新 功能 第 部分主要讨论比较单调的数学函数 第 部分将探讨专为操作浮点数而设计的函数
有时候您会对一个类熟悉到忘记了它的存在 如果您能够写出 java lang Foo 的文档 那么 Eclipse 将帮助您自动完成所需的函数 您无需阅读它的 Javadoc 例如 我使用 java lang Math(一个我自认为非常了解的类)时就是这样 但令我吃惊的是 我最近偶然读到它的 Javadoc —— 这可能是我近五年来第一次读到 我发现这个类的大小几乎翻了一倍 包含 种我从来没听说过的新方法 看来我要对它另眼相看了
Java&# ;语言规范第 版向 java lang Math(以及它的姊妹版 java lang StrictMath)添加了 种新方法 Java 又添加了 种 在本文中 我重点讨论其中的比较单调的数学函数 如 log 和 cosh 在第 部分 我将探讨专为操作浮点数(与抽象实数相反)而设计的函数
抽象实数(如 π 或 )与 Java double 之间的区别很明显 首先 数的理想状态是具有无限的精度 而 Java 表示法把数限销仿制为固定位数 在处理非常大和非常小的数时 这点很重要 例如 (二十亿零一)可以精确表示为一个 int 而不是一个 float 最接近的浮点数表示形式是 E — 即两亿 使用 double 数会更好 因为它们的位数更多(这是应该总是使用 double 数而不是 float 数的理由之一) 但它们的精度仍然受到一定限制
计算机算法(Java 语言和其他语言的算法)的第二个限制是它基于二进制而不是十进制 / 和 / 之类的分数可用十进制精确表示(分别是 和 ) 但用二进制表示时 就会出现重复的分数 如同 / 在用十进制表示时 就会变为 ……以 为基数 任何分母仅包含质数因子 和 的分数都可以精确表示 以 为基数 则只有分母是 的乘方的分数才可以精确表示 / / / / 等
这种不精确性是迫切需要一个 math 类的最主要的原因之一 当然 您可以只使用标准的 + 和 * 运算亏戚纤符以及一个简单的循环来定义三角函数和其他使用泰勒级数展开式的函数 如清单 所示
清单 使用泰勒级数计算正弦
public class SineTaylor { public static void main(String[] args) { for (double angle = ; angle <= *Math PI; angle += Math PI/ ) { System out println(degrees(angle) + + taylorSeriesSine(angle) + + Math sin(angle)); } } public static double degrees(double radians) { return * radians/ Math PI; } public static double taylorSeriesSine(double radians) { double sine = ; int sign = ; for (int i = ; i < ; i+= ) { sine += Math pow(radians i) * sign / factorial(i); sign *= ; } return sine; } private static double factorial(int i) { double result = ; for (int j = ; j <= i; j++) { result *= j; } return result; }}
开始运行得不错 只有一点小的误差 如果存在误差的话 也只是最后一位小数不同
但是 随着角度的增加 误差开始变大 这种简单的方法就不是很适用了
这里使用泰勒级数得到的结果实际上比我想象的要精确 但是 随着角度增加到 度 度( pi 弧度)以及更大时 泰勒级数就逐渐需要更多条件来进行准确计算 java lang Math 使用的更加完善的算法就避免了这一点
泰勒级数的效率也无法与现代桌面芯片的内置正弦函数相比 要准确快速地计算正弦函数和其他函数 需要非常仔细的算法 专门用于避免无意地将小的误差变成大的错误 这些算法一般内置在硬件中以更快地执行 例如 几乎每个在最近 年内组装的 X 芯片都具有正弦和余弦函的硬件实现 X VM 只需调用即可 不用基于较原始的运算缓慢地计算它们 HotSpot 利用这些指令显着加速了三角函数的运算
直角三角形和欧几里德范数
每个高中学生都学过勾股定理 在直角三角形中 斜边边长的平方等于两条直角边边长平方之和 即 c = a + b
学习过大学物理和高等数学的同学会发现 这个等式会在很多地方出现 不只是在直角三角形中 例如 R 的平方 二维向量的长度 三角不等式等都存在勾股定理 (事实上 这些只是看待同一件事情的不同方式 重点在于勾股定理比看上去要重要得多)
Java 添加了 Math hypot 函数来精确执行这种计算 这也是库很有用的一个出色的实例证明 原始的简单方法如下
public static double hypot(double x double y){ return x*x + y*y;}
实际代码更复杂一些 如清单 所示 首先应注意的一点是 这是以本机 C 代码编写的 以使性能最大化 要注意的第二点是 它尽力使本计算中出现的错误最少 事实上 应根据 x 和 y 的相对大小选择不同的算法
清单 实现 Math hypot
的实际代码/** ====================================================* Copyright (C) by Sun Microsystems Inc All rights reserved ** Developed at SunSoft a Sun Microsystems Inc business * Permission to use modify and distribute this* sofare is freely granted provided that this notice * is preserved * ====================================================*/#include fdlibm h #ifdef __STDC__ double __ieee _hypot(double x double y)#else double __ieee _hypot(x y) double x y;#endif{ double a=x b=y t t y y w; int j k ha hb; ha = __HI(x)& x fffffff; /* high word of x */ hb = __HI(y)& x fffffff; /* high word of y */ if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} __HI(a) = ha; /* a < |a| */ __HI(b) = hb; /* b < |b| */ if((ha hb)> x c ) {return a+b;} /* x/y > ** */ k= ; if(ha > x f ) { /* a> ** */ if(ha >= x ff ) { /* Inf or NaN */ w = a+b; /* for sNaN */ if(((ha& xfffff)|__LO(a))== ) w = a; if(((hb^ x ff )|__LO(b))== ) w = b; return w; } /* scale a and b by ** */ ha = x ; hb = x ; k += ; __HI(a) = ha; __HI(b) = hb; } if(hb < x b ) { /* b < ** */ if(hb <= x fffff) { /* subnormal b or */ if((hb|(__LO(b)))== ) return a; t = ; __HI(t ) = x fd ; /* t = ^ */ b *= t ; a *= t ; k = ; } else { /* scale a and b by ^ */ ha += x ; /* a *= ^ */ hb += x ; /* b *= ^ */ k = ; __HI(a) = ha; __HI(b) = hb; } } /* medium size a and b */ w = a b; if (w>b) { t = ; __HI(t ) = ha; t = a t ; w = sqrt(t *t (b*( b) t *(a+t ))); } else { a = a+a; y = ; __HI(y ) = hb; y = b y ; t = ; __HI(t ) = ha+ x ; t = a t ; w = sqrt(t *y (w*( w) (t *y +t *b))); } if(k!= ) { t = ; __HI(t ) += (k<< ); return t *w; } else return w;}
实际上 是使用这种特定函数 还是几个其他类似函数中的一个取决于平台上的 JVM 细节 不过 这种代码很有可能在 Sun 的标准 JDK 中调用 (其他 JDK 实现可以在必要时改进它 )
这段代码(以及 Sun Java 开发库中的大多数其他本机数学代码)来自 Sun 约 年前编写的开源 fdlibm 库 该库用于精确实现 IEE 浮点数 能进行非常准确的计算 不过会牺牲一些性能
以 为底的对数
对数说明一个底数的几次幂等于一个给定的值 也就是说 它是 Math pow() 函数的反函数 以 为底的对数一般出现在工程应用程序中 以 e为底的对数(自然对数)出现在复合计算以及大量科学和数学应用程序中 以 为底的对数一般出现在算法分析中
从 Java 开始 Math 类有了一个自然对数 也就是给定一个参数 x 该自然对数返回 e 的几次幂等于给定的值 x 遗憾的是 Java 语言的(以及 C Fortran 和 Basic 的)自然对数函数错误命名为 log() 在我读的每本数学教材中 log 都是以 为底的对数 而 ln 是以 e 为底的对数 lg 是以 为底的对数 现在已经来不及修复这个问题了 不过 Java 添加了一个 log () 函数 它是以 为底而不是以 e 为底的对数
清单 是一个简单程序 它输出整数 到 的以 和 e 为底的对数
清单 到 的各种底数的对数
public static void main(String[] args) { for (int i = ; i <= ; i++) { System out println(i + + Math log (i) + + Math log(i) + + lg(i)); } }
public static double lg(double x) { return Math log(x)/Math log( ); }}
下面是前 行结果
Math log () 能正常终止对数函数执行 或任何负数的对数返回 NaN
立方根
我不敢说我的生活中曾经需要过立方根 我也不是每天都要使用代数和几何的少数人士之一 更别提偶然涉足微积分 微分方程 甚至抽象代数 因此 下面这个函数对我毫无用处 尽管如此 如果意外需要计算立方根 现在就可以了 — 使用自 Java 开始引入的 Math cbrt() 方法 清单 通过计算 到 之间的整数的立方根进行了演示
清单 到 的立方根
public class CubeRoots { public static void main(String[] args) { for (int i = ; i <= ; i++) { System out println(Math cbrt(i)); } }}
下面是结果
结果显示 与平方根相比 立方根拥有一个不错的特性 每个实数只有一个实立方根 这个函数只在其参数为 NaN 时才返回 NaN
双曲三角函数
双曲三角函数就是对曲线应用三角函数 也就是说 想象将这些点放在笛卡尔平面上来得到 t 的所有可能值
x = r cos(t)y = r sin(t)
您会得到以 r 为半径的曲线 相反 假设改用双曲正弦和双曲余弦 如下所示
x = r cosh(t)y = r sinh(t)
则会得到一个正交双曲线 原点与它最接近的点之间的距离是 r
还可以这样思考 其中 sin(x) 可以写成 (ei x e i x)/ cos(x) 可以写成 (ei x + e i x)/ 从这些公式中删除虚数单位后即可得到双曲正弦和双曲余弦 即 sinh(x) = (e x e x)/ cosh(x) = (e x + e x)/
Java 添加了所有这三个函数 sh() Math sinh() 和 Math tanh() 还没有包含反双曲三角函数 — 反双曲余弦 反双曲正弦和反双曲正切
实际上 cosh(z) 的结果相当于一根吊绳两端相连后得到的形状 即悬链线 清单 是一个简单的程序 它使用 sh 函数绘制一条悬链线
清单 使用 sh() 绘制悬链线
import java awt *;
public class Catenary extends Frame {
private static final int WIDTH = ; private static final int HEIGHT = ; private static final double MIN_X = ; private static final double MAX_X = ; private static final double MAX_Y = ;
private Polygon catenary = new Polygon();
public Catenary(String title) { super(title); setSize(WIDTH HEIGHT); for (double x = MIN_X; x <= MAX_X; x += ) { double y = sh(x); int scaledX = (int) (x * WIDTH/(MAX_X MIN_X) + WIDTH/ ); int scaledY = (int) (y * HEIGHT/MAX_Y); // in puter graphics y extends down rather than up as in // Caretesian coordinates so we have to flip scaledY = HEIGHT scaledY; catenary addPoint(scaledX scaledY); } }
public static void main(String[] args) { Frame f = new Catenary( Catenary ); f setVisible(true); }
public void paint(Graphics g) { g drawPolygon(catenary); }
}
图 为绘制的曲线
图 笛卡尔平面中的一条悬链曲线
双曲正弦 双曲余弦和双曲正切函数也会以常见或特殊形式出现在各种计算中
符号
Math signum 函数将正数转换为 将负数转换为 仍然是 实际上 它只是提取一个数的符号 在实现 Comparable 接口时 这很有用
一个 float 和一个 double 版本可用来维护这种类型 这个函数的用途很明显 即处理浮点运算 NaN 以及正 和负 的特殊情况 NaN 也被当作 正 和负 应该返回正 和 负 例如 假设如清单 那样用简单的原始方法实现这个函数
清单 存在问题的 Math signum 实现
public static double signum(double x) { if (x == ) return ; else if (x < ) return ; else return ;}
首先 这个方法会将所有负 转换为正 (负 可能不好理解 但它确实是 IEEE 规范的必要组成部分) 其次 它会认为 NaN 是正的 实际实现如清单 所示 它更加复杂 而且会仔细处理这些特殊情况
清单 实际的 正确的 Math signum 实现
public static double signum(double d) { return (d == || isNaN(d))?d:Sign( d);}
public static double Sign(double magnitude double sign) { return rawCopySign(magnitude (isNaN(sign)? d:sign));}
public static double rawCopySign(double magnitude double sign) { return Double longBitsToDouble((Double doubleToRawLongBits(sign) & (DoubleConsts SIGN_BIT_MASK)) | (Double doubleToRawLongBits(magnitude) & (DoubleConsts EXP_BIT_MASK | DoubleConsts SIGNIF_BIT_MASK)));}
事半功倍
最有效的代码是从您未编写过的代码 不要做专家们已经做过的事情 使用 java lang Math 函数(新的和旧的)的代码将更快 更有效 而且比您自己编写的任何代码都准确 所以请使用这些函数