ฉันต้องการที่จะแปลงไปlong
int
หากค่าของlong
> int.MaxValue
ฉันมีความสุขที่จะปล่อยให้มันล้อมรอบ
วิธีที่ดีที่สุดคืออะไร?
ฉันต้องการที่จะแปลงไปlong
int
หากค่าของlong
> int.MaxValue
ฉันมีความสุขที่จะปล่อยให้มันล้อมรอบ
วิธีที่ดีที่สุดคืออะไร?
คำตอบ:
(int)myLongValue
เพียงแค่ทำ มันจะทำสิ่งที่คุณต้องการ (ทิ้ง MSB และรับ LSB) ในunchecked
บริบท (ซึ่งเป็นค่าเริ่มต้นของคอมไพเลอร์) มันจะโยนOverflowException
ในchecked
บริบทหากค่าไม่พอดีกับint
:
int myIntValue = unchecked((int)myLongValue);
new Random()
ใช้Environment.TickCount
ภายใต้ประทุน ไม่จำเป็นต้องหว่านเมล็ดด้วยตนเองด้วยเห็บนาฬิกา
unchecked
ดังนั้นหากคุณไม่ได้เปลี่ยนอย่างชัดเจนดังนั้นunchecked
คำหลัก (ดังที่แสดงในคำตอบนี้และความคิดเห็นของ @ ChrisMarisic ฯลฯ ) ไม่จำเป็นและint myIntValue = (int)myLongValue
มีความเท่าเทียมกัน อย่างไรก็ตามโปรดทราบว่าไม่ว่าคุณจะใช้unchecked
คำหลักหรือไม่ก็ตามคุณจะได้รับพฤติกรรมการตัดทอนที่ไม่เกี่ยวกับคณิตศาสตร์ที่อธิบายโดย @TJCrowder ที่ซึ่งสัญญาณสามารถพลิกในบางกรณีที่โอเวอร์โฟลว์ วิธีเดียวที่จะทำให้แน่ใจว่าถูกต้องทางคณิตศาสตร์อย่างแท้จริงคือการใช้checked(...)
บริบทซึ่งกรณีเหล่านั้นจะทำให้เกิดข้อยกเว้น
Convert.ToInt32(myValue);
แม้ว่าฉันจะไม่รู้ว่ามันจะทำอย่างไรเมื่อมันยิ่งใหญ่กว่า int.MaxValue
OverflowException
ซึ่งเป็นสิ่งที่ OP ต้องการ: msdn.microsoft.com/en-us/library/d4haekc4.aspx
Convert
ไม่ดี
if (value > Int32.MaxValue)
return Int32.MaxValue;
else
return Convert.ToInt32( value );
บางครั้งคุณไม่ได้สนใจจริงในมูลค่าที่เกิดขึ้นจริง แต่ในการใช้งานของมันเช่นการตรวจสอบ / แฮชโค้ด ในกรณีนี้วิธีการในGetHashCode()
ตัวเป็นตัวเลือกที่ดี:
int checkSumAsInt32 = checkSumAsIn64.GetHashCode();
GetHashCode
จะเป็นตัวเลือกที่เหมาะสม หากคุณอยู่หลังการตรวจสอบอย่างต่อเนื่อง - ค่าที่จะเหมือนกันเมื่อคุณเรียกใช้แอปของคุณในภายหลังไม่ควรใช้GetHashCode
เนื่องจากจะไม่รับประกันว่าจะเป็นอัลกอริทึมเดียวกันตลอดไป
วิธีที่ปลอดภัยและเร็วที่สุดคือการใช้ Bit Masking ก่อนส่ง ...
int MyInt = (int) ( MyLong & 0xFFFFFFFF )
ค่า Bit Mask ( 0xFFFFFFFF
) จะขึ้นอยู่กับขนาดของ Int เนื่องจากขนาด Int ขึ้นอยู่กับเครื่อง
unchecked
บริบทที่คุณจะไม่ได้รับunchecked
มากเกินไป- แต่คุณไม่จำเป็นต้องปิดบังเพื่อหลีกเลี่ยงการล้นดังนั้นจึงจำเป็นต้องแก้ปัญหาเฉพาะในchecked
บริบท] ตัวอย่างสำหรับ 16 บิต โฮลเดอร์ 16 บิตที่เซ็นชื่อ (-32768, 32767) การปิดบังด้วย 0xFFFF อนุญาตให้มีค่ามากถึง 65535, ทำให้เกิดการล้น IIRC สามารถปิดบังเพื่อหลีกเลี่ยงการลงชื่อบิต 0x7FFF หรือ 0x7FFFFFFF หากต้องการบวกเท่านั้น
มันสามารถแปลงโดย
วิธีการแปลง. ToInt32
แต่จะโยน OverflowException หากค่านั้นอยู่นอกช่วงของ Int32 Type การทดสอบพื้นฐานจะแสดงให้เราเห็นว่ามันทำงานอย่างไร:
long[] numbers = { Int64.MinValue, -1, 0, 121, 340, Int64.MaxValue };
int result;
foreach (long number in numbers)
{
try {
result = Convert.ToInt32(number);
Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.",
number.GetType().Name, number,
result.GetType().Name, result);
}
catch (OverflowException) {
Console.WriteLine("The {0} value {1} is outside the range of the Int32 type.",
number.GetType().Name, number);
}
}
// The example displays the following output:
// The Int64 value -9223372036854775808 is outside the range of the Int32 type.
// Converted the Int64 value -1 to the Int32 value -1.
// Converted the Int64 value 0 to the Int32 value 0.
// Converted the Int64 value 121 to the Int32 value 121.
// Converted the Int64 value 340 to the Int32 value 340.
// The Int64 value 9223372036854775807 is outside the range of the Int32 type.
ที่นี่มีคำอธิบายที่ยาวกว่า
จะไม่
(int) Math.Min(Int32.MaxValue, longValue)
เป็นวิธีที่ถูกต้องพูดทางคณิตศาสตร์?
longValue
ตัวแทนที่ใกล้ที่สุดint
ถ้าค่าดั้งเดิมมีค่ามาก แต่มันก็ยังขาดการรักษาที่เหมือนกันกับอินพุตที่เป็นลบซึ่งจะทำให้บิตที่สำคัญที่สุดเสียไปแทน คุณจะต้องเปรียบเทียบกับInt32.MinValue
ยัง แม้ว่าโปสเตอร์ต้นฉบับดูเหมือนจะไม่ต้องการที่จะหนีบ
วิธีการแก้ปัญหาต่อไปนี้จะตัดให้เป็น int.MinValue / int.MaxValue หากค่านั้นอยู่นอกขอบเขตจำนวนเต็ม
myLong < int.MinValue ? int.MinValue : (myLong > int.MaxValue ? int.MaxValue : (int)myLong)
วิธีที่เป็นไปได้คือการใช้ตัวดำเนินการโมดูโลเพื่อให้ค่าอยู่ในช่วง int32 เท่านั้นจากนั้นจึงส่งไปยัง int
var intValue= (int)(longValue % Int32.MaxValue);
myIntValue
สามารถสิ้นสุดเมื่อติดลบเมื่อmyLongValue
เป็นค่าบวก (4294967294 => -2
) และในทางกลับกัน (-4294967296 => 0
) ตัวอย่างเช่นเมื่อใช้CompareTo
งานการดำเนินการคุณจะไม่สามารถนำผลลัพธ์ของการลบอย่างใดอย่างหนึ่งlong
ออกจากกันเป็นความสุขint
และกลับมาได้อย่างมีความสุข สำหรับบางค่าการเปรียบเทียบของคุณจะให้ผลลัพธ์ที่ไม่ถูกต้อง