Java 小数转 36 进制

2021-01-12 16:08:25 +08:00
 douleL

java 小数如 Math.random()转 36 进制,求个方法

2200 次点击
所在节点    Java
16 条回复
crclz
2021-01-12 16:15:38 +08:00
整数部分就是模 K 取余( K 是进制)。
小数部分不一定能够精确转换。
小数部分首先确定你想要的小数位数 n,然后小数部分 tmp=小数部分*(K^n),n 为精度。然后截断 tmp=(int)tmp 。然后把 tmp 转换为 K 进制数,最后移动 n 位小数点。

以上是我凭借有限的知识想出来的,具体的专门的进制转换要具体去查专门的帖子或者解决方案。
douleL
2021-01-12 16:22:08 +08:00
我是想用 java 代码模拟 js 的 :Math.random().toString(36)
AoEiuV020
2021-01-12 16:30:17 +08:00
@douleL 建议装个 js 引擎直接跑 js 代码,
douleL
2021-01-12 16:31:18 +08:00
@AoEiuV020 我是这么干了 但是测试了下 性能耗时有点高 所以才想 java 代码替代的
ysc3839
2021-01-12 17:32:05 +08:00
去找一些嵌入式的很简单的 js 引擎,看 toString 的实现吧。
Xusually
2021-01-12 17:50:14 +08:00
Math.random()出来的小数,拆分成整数部分和小数部分分别用
Integer.toString(i, 36)
输出
Xusually
2021-01-12 17:53:51 +08:00
@Xusually emmm....小数部分有点问题,得想想,唉。
AoEiuV020
2021-01-12 18:02:19 +08:00
@douleL 简单写了一段试了下了 js 能对应上,但是精度是个大问题,无法模拟 js 的精度丢失,感觉 java 的 double 精度比 js 小,bigDecimal 精度又太大,
@Test
public void testRadix() {
assertEquals("0.o72tt3lcjtq", toString("0.6721285152844136", 36));
}
public String toString(String number, int radix) {
BigDecimal N = new BigDecimal(number);

StringBuilder sb = new StringBuilder();
BigInteger i = N.toBigInteger();
sb.append(i.toString(radix));
sb.append('.');
while(new BigDecimal(N.intValue()).compareTo(N) != 0 && sb.length() < 13) {
N = N.multiply(new BigDecimal(radix));
i = N.toBigInteger().mod(new BigDecimal(radix).toBigInteger());
sb.append(i.toString(radix));
}
return sb.toString();
}
AoEiuV020
2021-01-12 18:02:52 +08:00
v2ex 怎么发代码来着,
```java
@Test
public void testRadix() {
assertEquals("0.o72tt3lcjtq", toString("0.6721285152844136", 36));
}
public String toString(String number, int radix) {
BigDecimal N = new BigDecimal(number);

StringBuilder sb = new StringBuilder();
BigInteger i = N.toBigInteger();
sb.append(i.toString(radix));
sb.append('.');
while(new BigDecimal(N.intValue()).compareTo(N) != 0 && sb.length() < 13) {
N = N.multiply(new BigDecimal(radix));
i = N.toBigInteger().mod(new BigDecimal(radix).toBigInteger());
sb.append(i.toString(radix));
}
return sb.toString();
}
```
AoEiuV020
2021-01-12 18:03:03 +08:00
```
@Test
public void testRadix() {
assertEquals("0.o72tt3lcjtq", toString("0.6721285152844136", 36));
}
public String toString(String number, int radix) {
BigDecimal N = new BigDecimal(number);

StringBuilder sb = new StringBuilder();
BigInteger i = N.toBigInteger();
sb.append(i.toString(radix));
sb.append('.');
while(new BigDecimal(N.intValue()).compareTo(N) != 0 && sb.length() < 13) {
N = N.multiply(new BigDecimal(radix));
i = N.toBigInteger().mod(new BigDecimal(radix).toBigInteger());
sb.append(i.toString(radix));
}
return sb.toString();
}
```
AoEiuV020
2021-01-12 18:05:06 +08:00
zxCoder
2021-01-12 19:34:18 +08:00
转进制不是整数部分除进制取整,小数部分乘进制取整就好了
momocraft
2021-01-12 19:36:13 +08:00
直接生成随机字符串不好吗,js 的 toString 连定长都不是
douleL
2021-01-13 09:47:36 +08:00
@AoEiuV020 感谢老铁的援助 我目前也是找到类似的,和你的方法一样, 精度最后一位和 js 的不一样 暂时用的直接调用 js 引擎 还没找到解决方案
AoEiuV020
2021-01-13 09:52:53 +08:00
@momocraft 目的是仿 js,不是随机值,估计是做爬虫之类的东西吧,
LGA1150
2021-01-20 16:58:19 +08:00
> 感觉 java 的 double 精度比 js 小

java 的 double 和 js 的 number 都是 IEEE754 双精度……

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/744229

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX