معنى - random number javascript
كيف أقوم بتحويل عدد صحيح إلى ثنائي في JavaScript؟ (6)
طريقة بسيطة هي فقط ...
Number(42).toString(2);
// "101010"
أود أن أرى الأعداد الصحيحة ، إيجابية أو سلبية ، في ثنائي.
بدلا من هذا السؤال ، ولكن لجافا سكريبت.
محاولة
num.toString(2);
2 هو الجذر ويمكن أن يكون أي قاعدة بين 2 و 36
مصدر here
تحديث:
سيعمل هذا فقط للأرقام الموجبة ، بينما تمثل Javascript الأعداد الصحيحة الثنائية السلبية في تدوين الثنائي. لقد قمت بعمل هذه الوظيفة الصغيرة التي يجب أن تقوم بها ، لم أختبرها بشكل صحيح:
function dec2Bin(dec)
{
if(dec >= 0) {
return dec.toString(2);
}
else {
/* Here you could represent the number in 2s compliment but this is not what
JS uses as its not sure how many bits are in your number range. There are
some suggestions https://.com/questions/10936600/javascript-decimal-to-binary-64-bit
*/
return (~dec).toString(2);
}
}
كان لدي بعض المساعدة من here
هذه هي شفرتي:
var x = prompt("enter number", "7");
var i = 0;
var binaryvar = " ";
function add(n) {
if (n == 0) {
binaryvar = "0" + binaryvar;
}
else {
binaryvar = "1" + binaryvar;
}
}
function binary() {
while (i < 1) {
if (x == 1) {
add(1);
document.write(binaryvar);
break;
}
else {
if (x % 2 == 0) {
x = x / 2;
add(0);
}
else {
x = (x - 1) / 2;
add(1);
}
}
}
}
binary();
يمكن أن يشير الثنائي في "التحويل إلى ثنائي" إلى ثلاثة أمور رئيسية. نظام الرقم الموضعي ، والتمثيل الثنائي في الذاكرة أو نطاقات 32 بت. (لـ 64bit bitstrings ، انظر إجابة باتريك روبرتس )
1. نظام الأرقام
(123456).toString(2)
سيتم تحويل الأرقام إلى نظام الأرقام الموضعية 2 الأساسي. في هذا النظام يتم كتابة الأرقام السالبة بعلامات ناقص تمامًا كما هو الحال في العشرية.
2. التمثيل الداخلي
التمثيل الداخلي للأرقام هو نقطة عائمة 64 بت وتناقش بعض القيود في هذه الإجابة . لا توجد طريقة سهلة لإنشاء تمثيل سلسلة بت هذا في javascript ولا الوصول إلى وحدات البت المحددة.
3. أقنعة وبدائل المشغلين
لدى MDN نظرة عامة جيدة حول كيفية عمل مشغلي bitwise. الأهم:
يعامل مشغلو المعامل البيني المعاملات الخاصة بهم كسلسلة من 32 بت (أصفار وأخرى)
قبل أن يتم تشغيل العمليات ، يتم إرسال أرقام النقاط العائمة 64 بت إلى الأعداد الصحيحة الموقعة 32 بت. بعد تحويلها مرة أخرى.
هنا هو رمز المثال MDN لتحويل الأرقام إلى سلاسل 32 بت.
function createBinaryString (nMask) {
// nMask must be between -2147483648 and 2147483647
for (var nFlag = 0, nShifted = nMask, sMask = ""; nFlag < 32;
nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1);
return sMask;
}
createBinaryString(0) //-> "00000000000000000000000000000000"
createBinaryString(123) //-> "00000000000000000000000001111011"
createBinaryString(-1) //-> "11111111111111111111111111111111"
createBinaryString(-1123456) //-> "11111111111011101101101110000000"
createBinaryString(0x7fffffff) //-> "01111111111111111111111111111111"
الجواب :
function dec2bin(dec){
return (dec >>> 0).toString(2);
}
dec2bin(1); // 1
dec2bin(-1); // 11111111111111111111111111111111
dec2bin(256); // 100000000
dec2bin(-256); // 11111111111111111111111100000000
يمكنك استخدام Number.toString(2)
، ولكن لديها بعض المشاكل عند تمثيل الأرقام السالبة. على سبيل المثال ، الناتج (-1).toString(2)
هو "-1"
.
لإصلاح هذه المشكلة ، يمكنك استخدام عامل التفضيل الصحيح لعلاقة عدم الاتصال ( >>>
) لضغط رقمك على عدد صحيح غير موقعة.
إذا قمت بتشغيل (-1 >>> 0).toString(2)
فستقوم بتحويل عدد البتات 0 إلى اليمين ، مما لا يغير الرقم نفسه ولكن سيتم تمثيله كعدد صحيح غير موقعة. سينتج الكود أعلاه "11111111111111111111111111111111"
بشكل صحيح.
هذا السؤال لديه مزيد من التوضيح.
-3 >>> 0
(تحول منطقي صحيح) يجزم حججها إلى أعداد صحيحة غير موقعة ، وهذا هو السبب في حصولك على التمثيل التكاملي لـ 32 بت من -3.
ملاحظة 1 : تتوقع هذه الإجابة رقم كوسيطة ، لذا قم بتحويل حسابك وفقًا لذلك.
ملاحظة 2 : النتيجة هي سلسلة بدون الأصفار البادئة ، لذلك لوحة الصفر وفقا لذلك.
يحاول هذا الرد معالجة الأعداد الصحيحة ذات القيم المطلقة بين Number.MAX_SAFE_INTEGER
(أو 2**53-1
) و 2**31
. الحلول الحالية تعالج فقط الأعداد الصحيحة الموقعة في 32 بت ، لكن هذا الحل سينتج في شكل مكمل float64ToInt64Binary()
باستخدام float64ToInt64Binary()
:
// IIFE to scope internal variables
var float64ToInt64Binary = (function () {
// create union
var flt64 = new Float64Array(1)
var uint16 = new Uint16Array(flt64.buffer)
// 2**53-1
var MAX_SAFE = 9007199254740991
// 2**31
var MAX_INT32 = 2147483648
function uint16ToBinary() {
var bin64 = ''
// generate padded binary string a word at a time
for (var word = 0; word < 4; word++) {
bin64 = uint16[word].toString(2).padStart(16, 0) + bin64
}
return bin64
}
return function float64ToInt64Binary(number) {
// NaN would pass through Math.abs(number) > MAX_SAFE
if (!(Math.abs(number) <= MAX_SAFE)) {
throw new RangeError('Absolute value must be less than 2**53')
}
var sign = number < 0 ? 1 : 0
// shortcut using other answer for sufficiently small range
if (Math.abs(number) <= MAX_INT32) {
return (number >>> 0).toString(2).padStart(64, sign)
}
// little endian byte ordering
flt64[0] = number
// subtract bias from exponent bits
var exponent = ((uint16[3] & 0x7FF0) >> 4) - 1023
// encode implicit leading bit of mantissa
uint16[3] |= 0x10
// clear exponent and sign bit
uint16[3] &= 0x1F
// check sign bit
if (sign === 1) {
// apply two's complement
uint16[0] ^= 0xFFFF
uint16[1] ^= 0xFFFF
uint16[2] ^= 0xFFFF
uint16[3] ^= 0xFFFF
// propagate carry bit
for (var word = 0; word < 3 && uint16[word] === 0xFFFF; word++) {
// apply integer overflow
uint16[word] = 0
}
// complete increment
uint16[word]++
}
// only keep integer part of mantissa
var bin64 = uint16ToBinary().substr(11, Math.max(exponent, 0))
// sign-extend binary string
return bin64.padStart(64, sign)
}
})()
console.log('8')
console.log(float64ToInt64Binary(8))
console.log('-8')
console.log(float64ToInt64Binary(-8))
console.log('2**33-1')
console.log(float64ToInt64Binary(2**33-1))
console.log('-(2**33-1)')
console.log(float64ToInt64Binary(-(2**33-1)))
console.log('2**53-1')
console.log(float64ToInt64Binary(2**53-1))
console.log('-(2**53-1)')
console.log(float64ToInt64Binary(-(2**53-1)))
console.log('2**52')
console.log(float64ToInt64Binary(2**52))
console.log('-(2**52)')
console.log(float64ToInt64Binary(-(2**52)))
.as-console-wrapper {
max-height: 100% !important;
}
تتعامل هذه الإجابة بشدة مع تنسيق النقطة العائمة IEEE-754 مزدوج الدقة ، كما هو موضح هنا:
seee eeee eeee ffff ffff ffff ffff ffff ffff ffff ffff ffff ffff ffff ffff ffff
---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
[ uint16[3] ] [ uint16[2] ] [ uint16[1] ] [ uint16[0] ]
[ flt64[0] ]
little endian byte ordering
s = sign = uint16[3] >> 15
e = exponent = (uint16[3] & 0x7FF) >> 4
f = fraction
الطريقة التي يعمل بها الحل هو إنشاء اتحاد بين رقم نقطة عائم 64 بت ومصفوفة عدد صحيح 16 بت غير موقعة في ترتيب بايت صغير. بعد التحقق من صحة نطاق الإدخال الصحيح ، فإنه يلقي الإدخال إلى رقم نقطة عائمة الدقة المزدوجة على المخزن المؤقت ، ثم يستخدم الاتحاد للحصول على الوصول إلى قيمة البت وحساب السلسلة الثنائية استنادًا إلى البسط الثنائية والكترة الثنائية غير المتحيزة.
يتم تنفيذ الحل في ECMAScript 5 النقي باستثناء استخدام String#padStart()
، الذي يحتوي على polyfill متوفرة هنا .