新闻中心
J*aScript中实现字节数组位移:理解32位整数陷阱与位掩码应用

本文深入探讨了在j*ascript中实现类似go语言字节数组位移操作时遇到的常见问题。由于j*ascript的位运算符默认处理32位有符号整数,直接进行位移可能导致结果超出预期的8位字节范围。教程将详细解释这一机制,并提供通过应用 `& 0xff` 位掩码来正确截断结果,确保操作符合8位字节语义的解决方案,并附带完整示例代码。
1. J*aScript位操作与32位整数的特性
在Go语言中,byte 类型明确表示一个8位的无符号整数,其位操作自然遵循8位语义。然而,J*aScript在执行位操作(如 >, &, | 等)时,会将其操作数隐式转换为32位有符号整数。这意味着即使我们期望处理的是0-255范围内的字节值,J*aScript的位运算符也会在32位的上下文中进行计算。
考虑以下Go语言的字节左移逻辑:
func ShiftLeft(b []byte) []byte {
l := len(b)
if l == 0 {
panic("shiftLeft requires a non-empty buffer.")
}
output := make([]byte, l)
overflow := byte(0)
for i := int(l - 1); i >= 0; i-- {
output[i] = b[i] << 1 // Go's byte << 1 naturally handles 8-bit overflow
output[i] |= overflow
overflow = (b[i] & 0x80) >> 7
}
return output
}当尝试将其直接翻译成J*aScript时,可能会遇到以下问题:
function shiftLeft (b) {
var len = b.length;
if (len == 0) {
throw 'shiftLeft requires a non-empty buff
er';
}
var output = makeEmpty(len); // 假设 makeEmpty 返回一个填充0的数组
var overflow = 0;
for (var i = len - 1; i >= 0; i--) {
output[i] = b[i] << 1; // 问题所在:这里的结果可能是32位
output[i] |= overflow;
overflow = (b[i] & 0x80) >> 7;
}
return output;
}
// 辅助函数:创建一个填充0的数组
function makeEmpty(size) {
var result = [];
for (var i = 0; i < size; i++) {
result.push(0x00);
}
return result;
}
// 辅助函数:将二进制字符串转换为字节数组(此处仅处理单个字节)
// 注意:原问题中的 fromOctal 应为 fromBinary
function fromBinary(str) {
// parseInt(str, 2) 将二进制字符串解析为整数
var bytes = [parseInt(str, 2)];
return bytes;
}
console.log(shiftLeft(fromBinary("10000000"))); // 预期 [0],实际 [256]在这个例子中,当 b[i] 为 128 (二进制 10000000) 时,b[i]
2. 解决方案:使用位掩码 & 0xFF 进行截断
为了在J*aScript中模拟8位整数的位操作行为,我们需要在每次位移操作后,显式地将结果截断到8位。最有效的方法是使用位与操作符 & 配合掩码 0xFF。
0xFF 在二进制中表示 11111111。任何数与 0xFF 进行位与操作,都会保留该数的最低8位,并将其余高位清零。这完美地模拟了8位整数的溢出行为。
Openflow
一键极速绘图,赋能行业工作流
88
查看详情
将原始代码中的:
output[i] = b[i] << 1;
修改为:
output[i] = (b[i] << 1) & 0xFF;
通过添加 & 0xFF,即使 b[i]
3. 完整的J*aScript实现示例
以下是修正后的 shiftLeft 函数及相关辅助代码:
/**
* 创建一个指定大小的字节数组,并用0填充。
* @param {number} size 数组大小。
* @returns {number[]} 填充0的字节数组。
*/
function makeEmpty(size) {
var result = [];
for (var i = 0; i < size; i++) {
result.push(0x00); // 0x00 等同于 0
}
return result;
}
/**
* 对字节数组执行左移操作,模拟8位整数溢出。
* @param {number[]} b 待左移的字节数组。
* @returns {number[]} 左移后的字节数组。
* @throws {string} 如果输入数组为空。
*/
function shiftLeft (b) {
var len = b.length;
if (len === 0) {
throw 'shiftLeft requires a non-empty buffer';
}
var output = makeEmpty(len);
var overflow = 0; // 溢出位,0或1
// 从数组末尾(最低有效字节)开始处理
for (var i = len - 1; i >= 0; i--) {
// 1. 将当前字节左移一位,并用 & 0xFF 确保结果截断为8位
var shiftedValue = (b[i] << 1) & 0xFF;
// 2. 将前一个字节(或初始的0)的溢出位合并到当前字节
output[i] = shiftedValue | overflow;
// 3. 计算当前字节的最高位,作为下一个字节的溢出位
// (b[i] & 0x80) 提取第8位 (最高位)
// >> 7 将其右移7位,使其成为0或1
overflow = (b[i] & 0x80) >> 7;
}
return output;
}
/**
* 将二进制字符串转换为字节数组(此处仅处理单个字节)。
* @param {string} str 二进制字符串,如 "10000000"。
* @returns {number[]} 对应的字节数组。
*/
function fromBinary(str) {
// parseInt(str, 2) 将二进制字符串解析为整数
// 确保结果也是8位,尽管这里对于单个字节通常不是问题
var bytes = [parseInt(str, 2) & 0xFF];
return bytes;
}
// 测试用例
console.log("输入: [128] (二进制 10000000)");
console.log("输出:", shiftLeft(fromBinary("10000000"))); // 预期: [0]
console.log("\n输入: [1] (二进制 00000001)");
console.log("输出:", shiftLeft(fromBinary("00000001"))); // 预期: [2]
console.log("\n输入: [255] (二进制 111111以上就是J*aScript中实现字节数组位移:理解32位整数陷阱与位掩码应用的详细内容,更多请关注其它相关文章!
# 如何使用
# 大理小红书种草推广营销策划
# 渭南手机网站建设收费
# SEO教学设计模板
# 勒流网站建设咨询
# 营销推广的合同下载
# 营销网站建设的意义
# 商城微信营销推广
# 泉州网站建设动态
# 聊城原装网站优化公司
# 西凤酒网站搜索引擎优化
# 这一
# 的是
# 如何用
# 创建一个
# javascript
# 隐式
# 转换为
# 将其
# 掩码
# 运算符
# 隐式转换
# overflow
# 字符串解析
# 常见问题
# 字节
# go语言
# go
# java
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
Win11怎么查看电脑配置_Win11硬件配置检测工具使用
Bilibili动漫最新防封地址发布-Bilibili动漫2025年最稳正版入口推荐
J*aScript中高效清空DOM列表元素:解决for循环中断与任务管理问题
c++中的const_cast和reinterpret_cast怎么用_c++四种类型转换
Python getattr() 异常处理深度解析:避免程序意外退出
海棠电脑版入口_通过电脑访问海棠官网阅读
腾讯视频怎么使用多账号家庭管理_腾讯视频家庭多账号统一管理与权限分配教程
如何创建没有密码的Windows本地账户_跳过微软账户登录的技巧【教程】
夸克浏览器网页版最新地址 夸克浏览器官方入口合集
LocoySpider如何部署到云服务器_LocoySpider云部署的远程配置
12306选座怎么选到特殊座位_12306特殊座位选择注意事项
PHP表单数据传递:如何通过隐藏输入字段获取动态ID
高德地图公交到站提醒失败如何解决 高德提醒权限设置
格力空气能E5故障代码是什么情况_格力空气能E5代码解析与应对措施
在J*a中如何在J*a中使用异常机制记录错误日志_异常日志实践经验
fishbowl官网免费版 fishbowl养鱼网站入口
必由学官网快捷入口 必由学网页版在线学习平台
MAC如何安全彻底地删除文件_MAC使用终端命令确保文件无法被恢复
提升屏幕阅读器对“m”时间单位的播报准确性:HTML与CSS组合解决方案
一加手机电池耗电快怎么办_一加手机电池耗电快的解决方法
Mac怎么使用表情符号_Mac Emoji快捷键面板
手机屏幕碎了但能正常使用怎么办 手机外屏碎裂的修复建议
实现全屏滚动与导航点:专业教程
必由学在线入口 必由学网页版快速登录入口
Golang如何实现容器化日志收集与分析_Golang容器日志收集分析方法
AO3官网镜像链接 Archive of Our Own同人文在线浏览
响应式CSS Grid布局:优化网格项在小屏幕下的堆叠与宽度适配
支付宝如何管理隐私设置_支付宝隐私保护的配置技巧
QQ邮箱稳定登录入口_QQ邮箱官方网站网页版使用
lar*el怎么安全地存储和获取配置文件中的敏感信息_lar*el敏感信息安全存储方法
Win11怎么关闭触摸屏_Windows 11禁用HID符合标准触摸屏
如何优雅地扩展SprykerGlue后端API授权逻辑,使用spryker/glue-backend-api-application-authorization-connector-extension
外媒分析《GTA6》定价:卖100美元可以但真没必要!
精准捕获:如何在页面中监听除特定元素外的所有点击事件
邮编格式怎么匹配地址_根据邮编格式快速匹配详细地址的技巧
Win10怎么设置静态IP地址 Win10手动配置IP地址步骤【指南】
汽水音乐车机版横屏版7.1 汽水音乐车机版横屏版下载入口
机构:以往存储涨价周期小米利润率实际上有所改善 能转嫁给消费者等
漫蛙2在线漫画入口 漫蛙正版漫画网页版直达
2026春节假期时间安排 2026春节假日查询
向日葵客户端怎么进行远程CentOS控制_向日葵客户端远程CentOS控制操作教程
在J*a中如何开发在线活动报名与管理系统_活动报名管理项目实战解析
CSS Box Model与弹性按钮:维持布局稳定的动画实践
win11怎么查看应用耗电情况 Win11电池设置查看应用能耗排行榜【优化】
Gmail邮箱申请注册直达_Gmail邮箱免费注册PC版官网入口2025
b站赚钱渠道_b站收益来源
抖音网页版企业服务中心登录入口_抖音网页版企业登录平台
QQ邮箱官方网站登录入口_QQ邮箱网页版在线使用
Win11如何开启讲述人功能 Win11屏幕阅读器(讲述人)开启与关闭【教程】
德邦快递查询平台 德邦快递物流信息查询入口


2025-12-07
浏览次数:次
返回列表
er';
}
var output = makeEmpty(len); // 假设 makeEmpty 返回一个填充0的数组
var overflow = 0;
for (var i = len - 1; i >= 0; i--) {
output[i] = b[i] << 1; // 问题所在:这里的结果可能是32位
output[i] |= overflow;
overflow = (b[i] & 0x80) >> 7;
}
return output;
}
// 辅助函数:创建一个填充0的数组
function makeEmpty(size) {
var result = [];
for (var i = 0; i < size; i++) {
result.push(0x00);
}
return result;
}
// 辅助函数:将二进制字符串转换为字节数组(此处仅处理单个字节)
// 注意:原问题中的 fromOctal 应为 fromBinary
function fromBinary(str) {
// parseInt(str, 2) 将二进制字符串解析为整数
var bytes = [parseInt(str, 2)];
return bytes;
}
console.log(shiftLeft(fromBinary("10000000"))); // 预期 [0],实际 [256]