为什么 parseInt(0.0000008) === 8?

本文深入探讨了JavaScript中parseInt函数的特殊行为,特别是当应用于小数值时出现的异常情况。通过分析parseInt的工作原理,揭示了其在处理特定数值时返回意外结果的原因,并提供了几个示例来说明这一现象。

转自迷渡:Why parseInt(0.0000008) === 8?


IEEE 754

JavaScript 的数字系统是采用 IEEE 754,一开始看到这个问题,以为是 IEEE 754 导致的问题。

常见的问题有浮点数比较:

console.log((0.1 + 0.2) == 0.3);  // false
console.log((0.1 + 0.2) === 0.3); // false
console.log(0.1 + 0.2); // 0.30000000000000004

后来发现这问题并不会导致 parseInt(0.0000008) 变成 8,那么问题就可能在 parseInt 这个函数上。

## parseInt
> `parseInt(string, radix)`

parseInt 接受两个参数,第一个参数是要转换的字符串(忽略空白);第二个参数是基数。

例如:

parseInt('   12', 10);  // 12
parseInt('12**', 10);   // 12
parseInt('12.34', 10);  // 12
parseInt(12.34, 10);    // 12

最后一个例子让我们看到 parseInt 可以将数字类型转换成整数,但最好别这么做。

再来看下面这个例子:

parseInt(1000000000000000000000.5, 10); // 1

为什么会这样呢?

parseInt 的第一个类型是字符串,所以会将传入的参数转换成字符串,也就是 String(1000000000000000000000.5) 的结果为 '1e+21'parseInt 并没有将 'e' 视为一个数字,所以在转换到 1 后就停止了。

这也就可以解释 parseInt(0.0000008) === 8

String(0.000008);  // '0.000008'
String(0.0000008); // '8e-7'

从上面的程式码可以看出,小于 0.0000001(1e-7) 的数字转换成 String 时,会变成科学记号法,再对这个数进行 parseInt 操作就会导致这个问题发生。

结论

不要将 parseInt 当做转换 NumberInteger 的工具。

再补上一些悲剧:

parseInt(1/0, 19);      // 18
parseInt(false, 16);    // 250
parseInt(parseInt, 16); // 15
parseInt("0x10");       // 16
parseInt("10", 2);      // 2

参考资料

'''// 创建UI面板 var dialog = new Window('dialog', '生成多个文本图层'); dialog.orientation = 'column'; // 折叠和展开按钮组 var collapseExpandGroup = dialog.add('group'); collapseExpandGroup.orientation = 'row'; var expandButton = collapseExpandGroup.add('button', undefined, '展开'); var collapseButton = collapseExpandGroup.add('button', undefined, '折叠'); // 输入框组:每行内容 var inputGroup = dialog.add('group'); inputGroup.orientation = 'column'; inputGroup.add('statictext', undefined, '请输入每行内容:'); var inputField = inputGroup.add('edittext', [0, 0, 300, 150], '', {multiline: true}); inputField.characters = 30; inputField.minimumSize = [300, 150]; // 输入框组:最大行数 var rowGroup = dialog.add('group'); rowGroup.orientation = 'row'; rowGroup.add('statictext', undefined, '最大行数:'); var maxRowField = rowGroup.add('edittext', undefined, '10'); maxRowField.characters = 5; // 输入框组:字体大小 var fontSizeGroup = dialog.add('group'); fontSizeGroup.orientation = 'row'; fontSizeGroup.add('statictext', undefined, '字体大小:'); var fontSizeField = fontSizeGroup.add('edittext', undefined, '20'); fontSizeField.characters = 5; // 输入框组:字体颜色(RGB) var colorGroup = dialog.add('group'); colorGroup.orientation = 'row'; colorGroup.add('statictext', undefined, '字体颜色 (RGB):'); var redField = colorGroup.add('edittext', undefined, '0'); redField.characters = 3; var greenField = colorGroup.add('edittext', undefined, '0'); greenField.characters = 3; var blueField = colorGroup.add('edittext', undefined, '0'); blueField.characters = 3; // 输入框组:列宽 // var colSizeGroup = dialog.add('group'); // colSizeGroup.orientation = 'row'; // colSizeGroup.add('statictext', undefined, '列宽大小:'); // var colSizeField = colSizeGroup.add('edittext', undefined, '200'); // colSizeField.characters = 5; // 按钮组:确定和取消按钮 var buttonGroup = dialog.add('group'); buttonGroup.orientation = 'row'; var okButton = buttonGroup.add('button', undefined, '生成文本图层'); var cancelButton = buttonGroup.add('button', undefined, '取消'); // 声明展开高度变量 var expandedHeight; // 展开按钮点击事件 expandButton.onClick = function() { dialog.size.height = 500; }; // 折叠按钮点击事件 collapseButton.onClick = function() { dialog.size.height = collapseExpandGroup.size.height + buttonGroup.size.height; }; okButton.onClick = function() { try { // 获取输入框内容 var lines = inputField.text.split('\n'); var maxRow = parseInt(maxRowField.text, 10); var fontSize = parseInt(fontSizeField.text, 10); var red = parseInt(redField.text, 10); var green = parseInt(greenField.text, 10); var blue = parseInt(blueField.text, 10); // var colSize = parseInt(colSizeField.text, 10); var colSize = fontSize*4.1; // 创建文本图层 var doc = app.activeDocument; createTextLayers(lines, maxRow, fontSize, [red, green, blue], colSize); // 强制刷新文档显示 doc.activeLayer = doc.activeLayer; // 触发重绘 app.refresh(); // 可选:自动选择第一个生成的图层以便编辑 if(doc.artLayers.length > 0) { doc.activeLayer = doc.artLayers[doc.artLayers.length - 1]; } // 保持对话框打开,但给予用户视觉反馈 alert("文本图层已生成!\n你可以继续输入内容并再次生成。"); } catch (e) { alert("生成文本图层时出错: " + e); } }; var startRow = 1; // 起始行 var startCol = 0; function createTextLayers(lines, maxRow, fontSize, fontColor, colSize) { const textlist = lines; const fontFamily = "Adobe 黑体 Std"; // 字体 const ColsSpacing = (colSize / 72) * 2.54; const rowsSpacing = (fontSize / 72) * 2.54; // 间距计算(基于字体大小) for (var i = 0; i < textlist.length; i++) { var content = textlist[i]; var position = [startCol * ColsSpacing, startRow * rowsSpacing]; if (startRow % maxRow == 0) { startRow = 1; startCol++; } else { startRow++; } createTextLayer(content, position, fontSize, fontColor, fontFamily); } } function createTextLayer(content, position, size, color, font) { var doc = app.activeDocument; // 创建新文本图层 var textLayer = doc.artLayers.add(); textLayer.kind = LayerKind.TEXT; textLayer.name = content; // 设置文本内容 var textItem = textLayer.textItem; textItem.contents = content; // 设置文本位置 textItem.position = [position[0], position[1]]; // 设置文本大小 textItem.size = size; // 设置文本颜色 var rgbColor = new SolidColor(); rgbColor.rgb.red = color[0]; rgbColor.rgb.green = color[1]; rgbColor.rgb.blue = color[2]; textItem.color = rgbColor; // 设置字体 try { textItem.font = font; } catch (e) { // 忽略字体设置错误 } } // 取消按钮点击事件 cancelButton.onClick = function() { dialog.close(); }; // 显示UI dialog.center(); dialog.show(); try{ // dialog.size.height = titleBar.size.height + buttonGroup.size.height + resizeHandle.size.height + 10; dialog.size.height =50; } catch(e){ dialog.close(); } // 在对话框显示后获取展开高度 // expandedHeight = dialog.size.height; // dialog.size.height = expandedHeight; // 默认折叠窗口 - 修复:将这行移到获取展开高度之后""" 为什么我的jsx代码运行之后,点击生成文本图层之后,它不会每行往下排,并且满行之后向右一列呢
最新发布
09-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值