草庐IT

javascript - 如何从八 (8) 个 4 位整数创建 32 位整数?

coder 2024-05-10 原文

假设我有一个最大 32 位整数 -

const a =
  ((2 ** 32) - 1)
  
const b =
  parseInt("11111111111111111111111111111111", 2) // 32 bits, each is a one!
  
console.log(a === b) // true

console.log(a.toString(2))
// 11111111111111111111111111111111  (32 ones)

console.log(b.toString(2))
// 11111111111111111111111111111111  (32 ones)

到目前为止一切顺利。但现在假设我想使用八 (8) 个 4 位数字生成一个 32 位数字。这个想法很简单:将每个 4 位序列移位 (<<) 到位并将它们相加 (+) -

const make = ([ bit, ...more ], e = 0) =>
  bit === undefined
    ? 0
    : (bit << e) + make (more, e + 4)

const print = n =>
  console.log(n.toString(2))

// 4 bits
print(make([ 15 ])) // 1111

// 8 bits
print(make([ 15, 15 ])) // 11111111

// 12 bits
print(make([ 15, 15, 15 ])) // 111111111111

// 16 bits
print(make([ 15, 15, 15, 15 ])) // 1111111111111111

// 20 bits
print(make([ 15, 15, 15, 15, 15 ])) // 11111111111111111111

// 24 bits
print(make([ 15, 15, 15, 15, 15, 15 ])) // 111111111111111111111111

// 28 bits
print(make([ 15, 15, 15, 15, 15, 15, 15 ])) // 1111111111111111111111111111

// almost there ... now 32 bits
print(make([ 15, 15, 15, 15, 15, 15, 15, 15 ])) // -1 :(

我得到 -1预期的结果是全 32 位,或 11111111111111111111111111111111 .

更糟糕的是,如果我从预期的结果开始并向后工作,我会得到预期的结果 -

const c =
 `11111111111111111111111111111111`

const d = 
  parseInt(c, 2)
  
console.log(d) // 4294967295

console.log(d.toString(2) === c) // true

我尝试调试我的 make 函数以确保没有明显的问题 -

const make = ([ bit, ...more ], e = 0) =>
  bit === undefined
    ? `0`
    : `(${bit} << ${e}) + ` + make (more, e + 4)

console.log(make([ 15, 15, 15, 15, 15, 15, 15, 15 ])) 
// (15 << 0) + (15 << 4) + (15 << 8) + (15 << 12) + (15 << 16) + (15 << 20) + (15 << 24) + (15 << 28) + 0

这个公式看起来是正确的。我想这可能与 + 有关并切换到按位或(|),这应该在这里有效地做同样的事情 -

const a =
  parseInt("1111",2)
  
const b =
  (a << 0) | (a << 4)
  
console.log(b.toString(2)) // 11111111

const c =
  b | (a << 8)
  
console.log(c.toString(2)) // 111111111111

但是,我的 make 也遇到了同样的错误尝试组合所有八 (8) 个数字时的功能 -

const make = ([ bit, ...more ], e = 0) =>
  bit === undefined
    ? 0
    : (bit << e) | make (more, e + 4)

const print = n =>
  console.log(n.toString(2))


print(make([ 15, 15, 15, 15, 15, 15, 15 ])) // 1111111111111111111111111111 (28 bits)

print(make([ 15, 15, 15, 15, 15, 15, 15, 15 ])) // -1 :(

什么给了?

目标是使用 JavaScript 将八 (8) 个 4 位整数转换为单个 32 位整数 - 这只是我的尝试。我很好奇我的功能哪里出了问题,但我愿意接受其他解决方案。

我想避免将每个 4 位整数转换为二进制字符串,将二进制字符串混合在一起,然后将二进制字符串解析为单个 int。首选数值解决方案。

最佳答案

按位运算符将产生一个有符号 32 位数字,这意味着如果位置 31 的位(从右边的最低有效位开始计算,即位 0)为 1,则number 将为负数。

为避免这种情况发生,请使用 << 以外的其他运算符或 | ,这两者都会产生一个带符号的 32 位数字。例如:

(bit * 2**e) + make (more, e + 4)

强制无符号 32 位

位移运算符旨在将结果强制到带符号的 32 位范围内,至少在 mdn 上是这样声明的。 (在撰写本文时):

The operands of all bitwise operators are converted to signed 32-bit integers

事实上这并不完全正确。 >>>运算符是一个异常(exception)。 EcmaScript 2015, section 12.5.8.1声明操作数在移入 0 位之前映射到 unsigned 32 位。因此,即使您移动 位,您也会看到这种效果。

您只需将它应用于最终值一次,例如在您的 print 中功能:

console.log((n>>>0).toString(2))

BigInt 解决方案

如果您需要超过 32 位,并且您的 JavaScript 引擎支持 BigInt喜欢some已经这样做了,然后将 BigInts 用于按位运算符中涉及的操作数——这些将使用 32 位有符号数字包装(注意 n 后缀):

const make = ([ bit, ...more ], e = 0n) =>
  bit === undefined
    ? 0n
    : (bit << e) + make (more, e + 4n)

const print = n =>
  console.log(n.toString(2))

// Test
for (let i=1; i<20; i++) {
    print(make(Array(i).fill(15n))) // longer and longer array...
}

注意:如果您在运行上述命令时遇到错误,请使用 Chrome 重试...

关于javascript - 如何从八 (8) 个 4 位整数创建 32 位整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55390991/

有关javascript - 如何从八 (8) 个 4 位整数创建 32 位整数?的更多相关文章

  1. c# - 如何在数据绑定(bind)期间在datagridview中自定义格式数据 - 2

    我正在寻找一种格式化DataGridViewTextBoxColumn的方法,以便在数据绑定(bind)期间格式化要进行数据绑定(bind)的值。例如,我有一个CompanyName属性,当发生数据绑定(bind)时,我需要从CompanyName中获取前5个字母。我可以Hook不同的DataGridView事件(例如RowsAdded)并循环遍历所有行并执行此操作,但我想找到更复杂的方法来执行此操作。由于我已经决定使用数据绑定(bind),因此循环遍历数据并修改它有点违背数据绑定(bind)的概念。我所追求的是如何执行与下面相同的操作,但添加自定义格式设置逻辑:dataGridVie

  2. c# - 如何从 List<T> 中跳过(m).take(n)? - 2

    给定:List<int>list=newList<int>{1,2,3,4,5,6,7,8,9,10};如何实现以下代码?varlist2=list.skip(2).take(5); 最佳答案 只要您在using语句中包含System.Linq(并修复您的方法名称.Skip(2)和),您的示例代码就可以正常工作。取(5)).您的代码无法开箱即用的原因是.Skip和.Take是找到的扩展方法(与List类中定义的方法相反)在“System.Linq”命名空间中。 关

  3. c# - 如何指示何时故意忽略返回值 - 2

    在某些使用C/C++的情况下,我可以在语法上向编译器指示故意忽略返回值:intSomeOperation(){//Dotheoperationreturnreport_id;}intmain(){//Weexecutetheoperation,butinthisparticularcontextwe//havenouseofthereportidreturned.(void)SomeOperation();}我发现这是一种公平的做法,首先因为大多数编译器不会在这里生成警告,其次因为它明确地向future的开发人员表明作者有意识地选择忽略返回。它使作者的思路不含糊。据我所知,C#编译器不

  4. c# - 如何使 ListBox.ItemTemplate 可重用/通用 - 2

    我试图了解如何最好地扩展ListBox控件。作为一种学习体验,我想构建一个ListBox,其ListBoxItem显示一个CheckBox而不仅仅是文本。我使用ListBox.ItemTemplate以基本方式实现了它,显式设置了我想要数据绑定(bind)到的属性的名称。一个例子胜过一千个字,所以...我有一个用于数据绑定(bind)的自定义对象:publicclassMyDataItem{publicboolChecked{get;set;}publicstringDisplayName{get;set;}publicMyDataItem(boolisChecked,stringdi

  5. c# - 如何使用 StructureMap 通过代码定义默认构造函数? - 2

    我不知道如何通过代码为StructureMap(版本2.5)中的类型定义默认构造函数(当它存在重载时)。我想获取一个服务实例,容器必须向其中注入(inject)一个Linq2Sql数据上下文实例。我在我的“Bootstrap”方法中写了这个:ForRequestedType<MyDataContext>().TheDefault.Is.OfConcreteType<MyDataContext>();当我运行我的应用程序时,出现此错误:StructureMapExceptionCode:202NoDefaultInstancedefinedforPluginFam

  6. c# - 如何确定服务是否已经添加到 IServiceCollection - 2

    我正在创建辅助类以通过库的IServiceCollection简化接口(interface)的配置和注入(inject)。libraries构造函数包含许多可能早先注入(inject)的依赖项。如果它们尚未插入到IServiceCollection中,则帮助程序类应添加它们。如何检测接口(interface)是否已经注入(inject)?publicstaticvoidAddClassLibrary(thisIServiceCollectionservices,IConfigurationconfiguration){//ConstructorforClassLibraryrequir

  7. c# - 如何获得下一个工作日,不包括周末和节假日 - 2

    我有一个要求,我需要在日期字段上工作,所以要求是这样的我将该字段称为最短可能日期给日期加1如果最小可能日期恰好在添加1天后的周末(周六或周日),则显示下一个工作日,即周一如果可能的最短日期恰好是假日,则显示下一个工作日。(节假日1.1、1.5、3.10、25.12、26.12)如果最小可能日期恰好在加上1天后的周末(星期六或星期日),而后一天是假期,则显示下一个工作日。例如:+1天后,如果可能的最短日期是星期六,我们将不得不显示星期一。但如果星期一恰好是假期,那么我们必须显示星期二。我已经尝试通过多个if和else案例来解决上述问题,但只是想知道是否有任何通用且优雅的方法来解决这个问题

  8. c# - 如何解决错误 :the type does not appear to implement microsoft. practices.servicelocation.iservicelocator? - 2

    我是MVC的新手,我正在关注“AdamFreeman的PROASP.NETMVC4”。我目前正在研究它的第6章。我正在学习如何使用MVC4中的Ninject进行依赖注入(inject)。我已经按照书中的描述创建了应用程序。现在我不明白为什么会出现以下错误:该类型似乎没有实现microsoft.practices.servicelocation.iservicelocator这是我的Controller代码:publicclassHomeController:Controller{privateProduct[]products={newProduct{Name="Kayak&#

  9. c# - 如何遍历 XML 文件中的每个子节点? - 2

    我有一个XML文件,我想遍历每个子节点收集信息。这是我的C#代码,它只选取一个节点,我想在其子节点上使用foreach的FieldData。publicvoidLoadXML(){if(File.Exists("Data.xml")){//ReadingXMLXmlDocumentxmlDoc=newXmlDocument();xmlDoc.Load("Data.xml");//ThinksomethingneedstoreferenceChildnodes,soimayForeachthoughthemXmlNodeListdataNodes=xmlD

  10. C# DateTime - 如何检查时间部分是否为 NULL? - 2

    除了检查小时为0、分钟为0和秒为0之外,是否有任何简单的方法来检查DateTime值的时间部分是否为NULL?谢谢。 最佳答案 我发现这非常可读:varisTimeNull=(myDateTime.TimeOfDay==TimeSpan.Zero); 关于C#DateTime-如何检查时间部分是否为NULL?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7360750/

随机推荐

  1. C# - 检查变量是否已初始化 - 2

    我想检查一个变量是否在运行时以编程方式初始化。为了让这个原因不那么神秘,请看下面不完整的代码:strings;if(someCondition)s=someValue;if(someOtherCondition)s=someOtherValue;boolsIsUninitialized=/*assignvaluecorrectly*/;if(!sIsUninitialized)Console.WriteLine(s)elsethrownewException("Pleaseinitializes.");并完成相关位。一个hacky解决方案是用默认值初始化s:string

  2. c# - 如何遍历 XML 文件中的每个子节点? - 2

    我有一个XML文件,我想遍历每个子节点收集信息。这是我的C#代码,它只选取一个节点,我想在其子节点上使用foreach的FieldData。publicvoidLoadXML(){if(File.Exists("Data.xml")){//ReadingXMLXmlDocumentxmlDoc=newXmlDocument();xmlDoc.Load("Data.xml");//ThinksomethingneedstoreferenceChildnodes,soimayForeachthoughthemXmlNodeListdataNodes=xmlD

  3. c# - c# 中不区分大小写的 XML 解析器 - 2

    您对XML所做的一切都区分大小写,我知道这一点。但是,现在我发现自己处于这样一种情况,如果我以某种方式使xml名称/属性识别不区分大小写,我正在编写的软件将产生更少的错误。不区分大小写的XPath将是上帝派来的。在C#中是否有一种简单的方法/库可以做到这一点? 最佳答案 一个XMl文档可以有两个不同的元素,分别命名为:MyName和myName--目的是为了不同。将它们转换/视为同名是一个错误,可能会产生严重后果。如果不是上述情况,那么这里有一个更精确的解决方案,使用XSLT将文档处理成只有小写元素名称和小写属性名称的文档:<

  4. c# - 即使在 using block 中抛出异常,资源也会被释放吗? - 2

    这个问题在这里已经有了答案:关闭11年前。PossibleDuplicate:DoesDisposemethodstillgetcalledwhenExceptionisthrowninsideofUsingstatment?访问数据库时,我有很多usingblock。我想知道-如果必须在usingblock中抛出异常,即使未到达block的末尾,是否仍会处理必要的资源?或者我需要自己在catchblock中手动关闭它们吗?

  5. c# - 使用 LinqPad 将字符串转换为 Guid - 2

    当我在LinqPad中运行时varProductIds=frompinProductswherep.Id="F1FE990C-4525-4BFE-9E2C-A7AFFF0DDA1F"selectp;ProductIds.Dump();它给了我Cannotimplicitlyconverttype'string'to'System.Guid'我只是不知道如何将其正确转换为我猜的GUId 最佳答案 尝试使用Guid.Parse(stringguid)静态方法。varProductIds=f

  6. c# - 添加到 ICollection - 2

    我目前正在编写一个C#项目,我需要对该项目进行单元测试。对于我需要进行单元测试的方法之一,我使用了一个ICollection,它通常由列表框中的选定项填充。当我为它创建行的方法创建单元测试时ICollectionicollection=null;//Initialisetoanappropriatevalue如何创建此ICollection的实例和集合的项目? 最佳答案 ICollection是接口(interface),不能直接实例化。您需要实例化一个实现ICollection的类;例如,List<T>.此外,ICol

  7. C# DateTime - 如何检查时间部分是否为 NULL? - 2

    除了检查小时为0、分钟为0和秒为0之外,是否有任何简单的方法来检查DateTime值的时间部分是否为NULL?谢谢。 最佳答案 我发现这非常可读:varisTimeNull=(myDateTime.TimeOfDay==TimeSpan.Zero); 关于C#DateTime-如何检查时间部分是否为NULL?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7360750/

  8. c# - 我怎样才能让 OData DELETE 工作? - 2

    我已经创建了一个OData服务(WCF数据服务)和一个消费者来测试它。以前,当我尝试删除时,我收到WebDAV405错误消息,“方法不允许”。所以我用谷歌搜索并发现:http://nikhilthaker86.wordpress.com/2010/03/27/issue-hosting-restful-services-on-iis-7/我按照说明从IIS7的网站(服务)中删除了WebDav模块。现在我收到了这个错误信息:“HTTP错误500.21-内部服务器错误”处理程序“WebDAV”在其模块列表中有一个坏模块“WebDAVModule”模块:IISWeb核心通知:ExecuteR

  9. c# - 错误 "Missing operand after ' 类农算子”—— 'Bannon' 算子是什么? - 2

    在C#控制台应用程序上工作,我有一行:rowsFound=tempUsers.Select("EmailAddress='"+userData[2].ToString()+"'");rowsFound是一个DataRow[],tempUsers是一个DataTable,而userData是一个SqlDataReader。userData的索引错误(它是1),我得到了这个错误:System.Data.SyntaxErrorExceptionwasunhandledMessage=Syntaxerror:Missingoperandafter

  10. c# - 如何将 object[] 转换为更具体类型的数组 - 2

    如果我在编译时知道类型或者它是一个通用参数,这将非常简单,因为我可以做类似myArray.Cast<T>()的事情但我实际上拥有的基本上是这个。我没有已知类型或通用参数。我有一个System.Type变量。//couldactuallybeanythingelseTypemyType=typeof(string);//ialreadyknowalltheelementsarethecorrecttypesobject[]myArray=newobject[]{"foo","bar"};我可以使用某种反射魔法来获得string[]吗?包含相同数