Thêm 1 vào một biến không hoạt động như mong đợi (số học Bash)


16

Nếu tôi viết như sau vào một bash terminal:

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

Tôi nhận được 11, không phải 13 như tôi mong đợi !!!!!

Tôi đã đi vòng quanh và tôi không thể giải thích điều đó, hoặc tìm hiểu làm thế nào tôi có thể tăng số lượng. (Tôi thực sự muốn kết thúc với B = "0013" và tăng từng lần một khi tôi đang sử dụng điều này làm tiền tố cho các bản sao lưu của mình)


2
Cảnh giác với các số 0 đứng đầu về cơ bản bất kỳ ngôn ngữ nào có nguồn gốc trên UNIX. Điều này thường có nghĩa là bát phân.
Joshua

Không, bạn không phải là bạn nhận được 1011 nhị phân
Ken Mollerup

Câu trả lời:


28

Đó là bởi vì các số bắt đầu bằng 0được coi là Octal bash, do đó nó đang thực hiện phép cộng Octal (Base 8). Để có được bổ sung thập phân cho cấu trúc này, bạn cần xác định rõ ràng Cơ sở hoặc không sử dụng 00hoàn toàn.

Đối với số thập phân, Cơ sở là 10, ký hiệu là 10#:

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

5

Bạn có thể thử lệnh này để có câu trả lời:

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

Thông tin thêm về bclệnh có thể được tìm thấy ở đây .

bc trang nam:

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
Thay vì sử dụng echovà một đường ống, bạn có thể sử dụng cú pháp "chuỗi ở đây" của Bash. Hiệu quả là như nhau, nhưng IMHO "ở đây chuỗi" là đẹp hơn: bc <<< "$A + 1":-)
Byte Commander

Giới thiệu một hoặc hai câu của bclệnh ngoài hereliên kết sẽ hữu ích.
WinEunuuchs2Unix

2

Một phương pháp thay thế có thể là giữ các biến của bạn dưới dạng số nguyên và chuyển đổi chúng thành một chuỗi ở cuối:

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

Phong cách làm việc với các số nguyên trong toán học và chuyển đổi thành chuỗi cho câu trả lời trực quan hơn đối với tôi khi tôi đã quen với lập trình BASIC. Tôi đánh giá cao Bash không có kiểu gõ thay đổi như C và BASIC nhưng giả vờ nó làm tôi hạnh phúc.


Đây là một thử nghiệm để làm nổi bật vấn đề tôi đang gặp phải. Tôi đọc biến ban đầu bằng cách lấy đầu ra của một lệnh khác là văn bản và có các số 0 đứng đầu.
Robert3452

À ... lịch sử luôn giải thích cách chúng ta đến hiện tại.
WinEunuuchs2Unix

@ Robert3452 Bạn cũng có thể loại bỏ các số 0 hàng đầu:A="0012"; A=$((10#$A))
wjandrea
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.