การเพิ่ม 1 ให้กับตัวแปรไม่ทำงานตามที่คาดไว้ (Bash arithmetic)


16

ถ้าฉันเขียนสิ่งต่อไปนี้ลงใน bash terminal:

A="0012"
B=$((A+1))
echo $B

ฉันได้ 11, ไม่ใช่ 13 ตามที่คาดไว้ !!!!!

ฉันเล่นไปรอบ ๆ และไม่สามารถอธิบายได้เลยหรือหาวิธีเพิ่มจำนวนได้ (จริง ๆ แล้วฉันต้องการที่จะจบลงด้วย B = "0013" และเพิ่มขึ้นหนึ่งครั้งในขณะที่ฉันใช้สิ่งนี้เป็นคำนำหน้าของการสำรองข้อมูลของฉัน)


2
ระวังเลขศูนย์นำหน้าด้วยภาษาใดก็ตามที่มีต้นกำเนิดบน UNIX ซึ่งโดยปกติจะหมายถึงฐานแปด
โจชัว

ไม่คุณไม่ใช่คุณได้รับ 1,011 binary
Ken Mollerup

คำตอบ:


28

นั่นเป็นเพราะตัวเลขที่เริ่มต้นด้วย0จะถือว่าเป็น Octal โดยbashดังนั้นมันจะทำ Octal (ฐาน 8) นอกจากนี้ ในการรับการบวกทศนิยมสำหรับโครงสร้างนี้คุณต้องกำหนดฐานอย่างชัดเจนหรือไม่ใช้00ทั้งหมด

สำหรับทศนิยมฐานคือ 10 แสดงโดย10#:

$ A="10#0012"
$ echo $((A+1))
13

5

คุณอาจลองคำสั่งนี้เพื่อรับคำตอบ:

A="0012"
echo $A + 1 | bc

ข้อมูลเพิ่มเติมเกี่ยวกับbcคำสั่งที่สามารถพบได้ที่นี่

bc หน้าคน:

NAME
       bc - An arbitrary precision calculator language

SYNTAX
       bc [ -hlwsqv ] [long-options] [  file ... ]

DESCRIPTION
       bc is a language that supports arbitrary precision numbers with interactive execution of statements.  There are some similarities
       in the syntax to the C programming language.  A standard math library is available by command line  option.   If  requested,  the
       math  library is defined before processing any files.  bc starts by processing code from all the files listed on the command line
       in the order listed.  After all files have been processed, bc reads from the standard input.  All code is executed as it is read.
       (If a file contains a command to halt the processor, bc will never read from the standard input.)

       This  version of bc contains several extensions beyond traditional bc implementations and the POSIX draft standard.  Command line
       options can cause these extensions to print a warning or to be rejected.  This document describes the language accepted  by  this
       processor.  Extensions will be identified as such.

4
แทนที่จะใช้echoและไปป์คุณสามารถใช้ไวยากรณ์ "here string" ของ Bash ได้ ผลจะเหมือนกัน แต่ IMHO "สตริงที่นี่" นั้นสวยงามกว่า: bc <<< "$A + 1":-)
ผู้บัญชาการ Byte

การแนะนำประโยคหนึ่งหรือสองประโยคของbcคำสั่งเพิ่มเติมจากhereลิงก์จะเป็นประโยชน์
WinEunuuchs2Unix

2

วิธีอื่นอาจจะทำให้ตัวแปรของคุณเป็นจำนวนเต็มและแปลงเป็นสตริงที่ส่วนท้าย:

A=12
B=$((A+1))
echo $B
13
C=$( printf '%04d' $B )
echo $C
0013

รูปแบบของการทำงานกับเลขจำนวนเต็มในคณิตศาสตร์และการแปลงเป็นสตริงสำหรับคำตอบนั้นง่ายกว่าสำหรับฉันเมื่อฉันคุ้นเคยกับการเขียนโปรแกรมพื้นฐาน ฉันขอขอบคุณ Bash ที่ไม่มีการพิมพ์ที่หลากหลายเช่น C และ BASIC แต่การแกล้งมันทำให้ฉันมีความสุข


นี่คือการทดสอบเพื่อเน้นปัญหาที่ฉันมี ฉันอ่านตัวแปรเริ่มต้นโดยการเอาท์พุทของคำสั่งอื่นซึ่งเป็นข้อความและมีศูนย์นำหน้า
Robert3452

อ่า ... ประวัติศาสตร์อธิบายว่าเราไปถึงปัจจุบันได้อย่างไร
WinEunuuchs2Unix

@ Robert3452 คุณยังสามารถตัดเลขศูนย์นำ:A="0012"; A=$((10#$A))
wjandrea
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.