Как мне распечатать пи (3.14159)? [закрыто]

35

Какая команда может напечатать пи для меня? Я хочу указать, сколько цифр он печатает, я не смог ничего найти в Интернете. Я просто хочу иметь возможность печатать пи.

Отображаемое имя
источник
28
Выберите язык: rosettacode.org/wiki/Pi
Марк Плотник,
4
Обратите внимание, что вам будет веселее, если вы хотите больше цифр, чем около 15.
Thorbjørn Ravn Andersen
2
@DisplayName: это означает, что вы больше не можете использовать любую программу, которая хранит / рассчитывает PI для внутреннего использования с использованием значений с плавающей запятой двойной точности (что обычно является встроенным типом данных FP с наивысшей точностью, доступным в большинстве языков).
Matteo Italia
5
Мое решение, десятилетия назад до того, как это обычно предоставлялось языковыми библиотеками, заключалось в том, чтобы запомнить его в большем количестве мест, чем те, которые я когда-либо использовал с плавающей запятой: 3.1415926535897932384626 обычно достаточно близко для практических целей, и даже самых непрактичных - что-нибудь реальное -world будет иметь больше ошибок, чем в других числах, и для теории я бы придерживался символического, а не числового значения.
Кешлам
3
Интерес @syntaxerror не имеет значения. Если бы вы отправили вопрос с голыми фотографиями знаменитостей, это получило бы тысячи просмотров и, возможно, голосов. Это не делает это по теме. Этот вопрос является классическим примером слишком широким. Просто посмотрите на количество ответов. Также обратите внимание, что в ОП не указаны какие-либо ограничения, что делает возможные ответы практически бесконечными. В любом случае закрытие не удаляет. Вопрос и все его 23 ответа все еще будут здесь. Закрытие просто означает, что больше не принимаются ответы. Нам действительно нужно еще больше способов напечатать π?
Тердон

Ответы:

52

Вы можете использовать эту команду:

echo "scale=5; 4*a(1)" | bc -l
3.14159

Где масштаб это количество цифр после десятичной точки.

Ссылка: http://www.tux-planet.fr/calculer-le-chiffre-pi-en-ligne-de-commande-sous-linux/

Abey
источник
12
Сокращенный вариант в bashи другие оболочки , поддерживающие здесь строки: bc -l <<< "scale=5; 4*a(1)".
Пабук
2
Интересно, сколько цифр это может идти?
DisplayName
4
@DisplayName довольно много. scale=1000дает 999 правильных цифр довольно быстро (последняя цифра отключена на 1, разумно, так как мы вычисляем pi / 4 и затем умножаем на 4). scale=4000дает 4000 правильных цифр за несколько секунд. scale=10000занимает больше времени, чем у меня есть терпение, но, вероятно, дает 9999 или 10000 правильных цифр.
Хоббс
4
Это дает неверный результат на моей машине, набрав 'echo "scale = 5; 4 * a (1)" | bc -l 'возвращает 3.14156, когда последняя цифра должна равняться 9
Джордан Бентли
61

Если вы tex(1)установили:

tex --version | head -1 | cut -f2 -d' '
Стивен Д
источник
13
Это почти стоит того, чтобы быть умным. Хотя вывод этого изменяется при обновлении пакета. Должны ли мы считать это признаком или ошибкой?
CVN
8
@ MichaelKjörling На самом деле, это меняется, чтобы быть более точным приближением к пи.
Abrixas2
@ Abrixas2 Да, я знаю. С последней версией TeX является версия π.
CVN
30
@DavidRicherby Меньшее количество цифр может быть напечатано с помощью дополнительного вызова cut. Можно распечатать больше цифр, ожидая долго и снова выполнив команду.
Стивен Д
1
@Ruslan зависит от реализации. Я бы ожидал, что в этом конкретном случае это будет сделано «правильно».
Турбьёрн Равн Андерсен
23

Для печати с произвольной точностью вы можете использовать bcи формулу pi = 4*atan(1):

# bc -l
scale=<your precision>
4*a(1)
Abrixas2
источник
2
Есть что-то смешное в scaleварианте, pi = 3.141592..но с чего echo "scale=5; 4*a(1)" | bc -l => 3.14156я тогда ожидал увидеть 3.14159?
fduff
7
scaleзадает точность, используемую для расчета, поэтому при scale=5любой операции не будет использоваться более пяти дробных цифр для любой атомарной операции.
Abrixas2
20

Если вы хотите что-то, что может вычислить значение π, то есть несколько подходов. Возможно, наиболее очевидным решением было бы использовать готовый пакет, такой как pi(ссылка на пакет Debian) , который, если доверять описанию пакета Debian, может вычислить значение с произвольной точностью, ограниченной только памятью.

piна самом деле пример, который включен в библиотеку CLN (библиотека классов для чисел) . Он включает в себя примеры приложений, которые предоставляют инструменты для генерации произвольных длин чисел, таких как Pi, Fibonacci и т. Д. Пакеты CLN доступны предварительно упакованными в Debian / Ubuntu (это то, на что указывает ссылка на Debian выше).

Примеры
$ ./pi 10
3.141592653

$ ./pi 20
3.1415926535897932384

ПРИМЕЧАНИЕ . Источник этих примеров находится здесь в источнике для базы кода CLN .

Другие дистрибутивы

мягкая фетровая шляпа

На Fedora мне пришлось скачать исходный архив и собрать его самостоятельно, но он собирался без особых хлопот. По какой-то причине пакет clnв Fedora включает только библиотеку, но пренебрегает примерами, которые доступны в версии Debian / Ubuntu (см. Выше).

арочный

Arch обеспечивает ту же программу в на clnупаковке (спасибо Amphiteót ).

CVn
источник
Да, хех, я имел в виду общую стоимость, которую я просто набрал, что у меня в голове.
DisplayName
2
«Общая стоимость» ?? Это означает, что...?
Кайл Стрэнд,
2
@DisplayName прочитайте остальную часть ответа. Специальная программа вроде piзвучит как то, что вы ищете. pi 300Например, вы можете напечатать первые 300 цифр.
Тердон
3
@KyleStrand Я нашел поистине изумительный ответ на этот вопрос, который этот комментарий слишком узок, чтобы его содержать. Эй, это сработало для Ферма !
Тердон
Я хотел бы знать, почему это получило два отрицательных голоса. Разве люди, которые проголосовали против, не прочитали ответ, прежде чем решили, что он бесполезен?
CVN
17

Для до миллиона цифр вы можете использовать следующее (здесь для 3000 цифр):

curl --silent http://www.angio.net/pi/digits/pi1000000.txt | cut -c1-3000
Энтон
источник
2
Это имеет дополнительное преимущество, заключающееся в том, что он должен быть достаточно близок к сложности O (1). Или, может быть, это не выгодно в конце концов ...
CVN
7
Кроме того, трудно сказать, что любое сетевое взаимодействие является O (1) временной сложностью в практическом мире. : P
HalosGhost
2
@HalosGhost Для наших целей (по сравнению с вычислением n цифр числа Пи каждый раз) загрузка фиксированного объема данных с определенного сервера по сети, вероятно, будет эффективно O (1), тогда как вычисление n цифр числа Пи, вероятно, будет по крайней мере, что-то вроде O (log n) и, возможно, выше (я не знаком с этими алгоритмами). Фактическая загрузка данных, вероятно, займет значительно больше времени, чем накладные расходы, чтобы начать загрузку, следовательно, время загрузки доминирует, и вы получите где-то в окрестности O (1) при разумно фиксированной скорости передачи данных. Следовательно, O (1).
CVN
4
@ MichaelKjörling Когда вы говорите O (1), разве вы не имеете в виду O (n)? Время загрузки в линейном виде в количестве нужных вам цифр, отсюда O (n).
CodesInChaos
1
@CodesInChaos Нет, время загрузки является постоянным (с учетом постоянной скорости передачи), потому что вы загружаете постоянное количество цифр (один миллион, здесь). Если (в данном конкретном случае) curl не достаточно умен, чтобы печатать во время загрузки и прекратить загрузку после разрыва канала, потому что cutвыход? Если это так, я согласен, это будет O (n).
CVN
15

Некоторые другие ответы показывают неправильные цифры в последних местах вывода. Ниже приведен вариант ответа с использованием,bc но с правильно округленным результатом. Переменная sсодержит количество значащих цифр (в том числе 3перед десятичной точкой).

Круглая половина

$ bc -l <<< "s=5; scale=s+2; pi=4*a(1)+5*10^(-s); scale=s-1; pi/1"
3.1416

Округлить (усечь)

$ bc -l <<< "s=5; scale=s+2; pi=4*a(1); scale=s-1; pi/1"
3.1415

Объяснение округления

Округление выполняется непосредственно в bc. Это не имеет ограничения для команды, printfкоторая использует представление doubleтипа языка C для чисел, которые имеют точность около 17 значащих цифр. Смотрите ответ с printfокруглением .

scale=s-1устанавливает количество цифр для усечения. pi/1делит результат на 1, чтобы применить усечение. Простой piне усекает число.

Завершают половина вверх требует , чтобы добавить 5 к первой цифре , которая будет отрезана (5 × 10 -s ) , так что в случае цифр высших равного 5 последняя цифра , которая останется , будет увеличиваться.

Из тестов Хоббса кажется, что трех дополнительных цифр, которые будут округлены / обрезаны ( scale=s+2) будет достаточно даже для очень длинных чисел.

Здесь строки

Приведенные выше примеры использования здесь строки , которые поддерживаются, например , в bash, kshи zsh. Если ваша оболочка не поддерживает здесь, используйте string echoи pipe:

$ echo "s=5; scale=s+2; pi=4*a(1); scale=s-1; pi/1" |  bc -l
3.1415
pabouk
источник
2
Вычисление трех дополнительных цифр для округления не является «правильным округлением», как вы заявляете в комментарии. Во-первых, у вас нет ограничения на ошибку вычисления. Если это может быть неправильно на 3 юнитах в последнем месте, как утверждает fduff, почему бы не ошибаться на 1000 юнитов в последнем месте? Во-вторых, смотрите «Дилемма производителя стола».
Сложно посмотреть биографию
12

perl одна строка (с использованием bignum ):

perl -Mbignum=bpi -wle 'print bpi(NUM)'

например

perl -Mbignum=bpi -wle 'print bpi(6)'
3.14159
don_crissti
источник
Для 10.000 цифр: около 8 минут в perl, менее 4 в bc. Не самый быстрый.
Исаак
9

С python2:

$ python -c "import math; print(str(math.pi)[:7])"
3.14159
MKC
источник
4
Для полноты картины это решение зависит от python2.
HalosGhost
После редактирования, (..)это работает в Python 2 и 3. Кажется, только 12 цифр.
Антон
$ Питон -c "импорта математики, печать (формат (math.pi, '.400f'))" 3,1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Артем Шитов
1
@ArtemShitov - мой плохой, попробуйте импортировать gmpy2 (если он установлен): python -c "import gmpy2; print(str(gmpy2.const_pi(8192))[:400])". Увеличьте точность для большего количества цифр ... напримерpython -c "import gmpy2; print(str(gmpy2.const_pi(16384))[:4400])"
don_crissti
1
Быстрее всего я смог найти from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)всего пару секунд на миллион цифр. Совсем неплохо !!!.
Исаак
7

Используя Ruby:

require "bigdecimal"
require "bigdecimal/math"
include BigMath

BigDecimal(PI(100)).round(9).to_s("F")

3.141592654
ножка
источник
1
Один лайнер:ruby -e 'require "bigdecimal"; require "bigdecimal/math"; include BigMath; puts BigDecimal(PI(100)).round(9).to_s("F")'
4

В Баш:

$ read -a a <<< $(grep M_PIl /usr/include/math.h) ; echo ${a[3]} | tr -d L
3.141592653589793238462643383279502884
Эдуард Тиль
источник
@ Amphiteóth afmtoditтребует , groffчтобы быть установлен. Здесь, на Ubuntu (и вкусах), это не стандартно. JFYI.
синтаксическая ошибка
@syntaxerror Спасибо, хорошая мысль! Я удалил свой пример. Моя точка зрения заключалась в том, что когда я читал этот AI, он запускал grepмою систему в поисках константы и находил ее в нескольких местах. Вот почему это было +1 для меня!
3

Очень прост в PHP, используя встроенную функцию pi ():

<?php 
echo round(pi(), 2);
?>
Марк Фарнелл
источник
1
Можете ли вы отредактировать это, чтобы дать версию командной строки?
curiousdannii
3

Как я пропустил этот вопрос ...

Вот небольшая моя Python-программа, которую я опубликовал пару недель назад на Stack Overflow. Это не особенно быстро, но может делать много цифр. :) Однако, как я уже упоминал в этом потоке, я обычно использую модуль mpmath в Python для арифметики произвольной точности, а mpmath имеет довольно быстрый пи-мейкер.

Например,

time python -c "from mpmath import mp;mp.dps=500000;print mp.pi" >bigpi

real    0m4.709s
user    0m4.556s
sys     0m0.084s

500000 десятичных чисел числа пи за менее чем 5 секунд не слишком плохие, ИМХО, учитывая, что он работает на машине с одноядерным процессором 2 ГГц, 2 гигабайтами оперативной памяти и записывает на устаревший диск IDE.

PM 2Ring
источник
Попробуйте from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)(после pip3 установить mpmath) под две секунды для миллиона цифр. Совсем неплохо !!!.
Исаак
2

Если вы node.jsустановили, это сделает все возможное, чтобы найти пи для вас, хотя лучше не очень хорошо:

node -e 'for(a=0,b=4E8,m=Math,r=m.random;b--;)a+=(1>m.sqrt((c=r())*c+(d=r())*d));console.log(a/1E8)'

Пример выходов:

3.14157749
3.1416426
3.14159055
3.14171554
3.14176165
3.14157587
3.14161137
3.14167685
3.14172371
Павел
источник
4
Чем короче node -e 'console.log(Math.PI)', тем лучше, чем лучше.
chbrown
1
@chbrown Это не удовлетворяет «несерьезным» требованиям ОП.
Пол
1
Какое «несерьезное» требование? ОП только что заявил, что они просят повеселиться, а не хотят, чтобы ответы были «несерьезными». Что это значит в любом случае? Что то типа echo pie?
Тердон
Я напечатал это потому, что когда вы задаете вопросы, иногда люди говорят, что «это не фабрика написания сценариев», поэтому я сказал, что, поскольку для этого нет реальной причины, я просто хочу знать, как печатать пи.
DisplayName
@ Amphiteóth Запуск моего компьютера занимает около 20 секунд. Возможно, вам просто нужно дать ему немного времени.
Пол
2

Метод Монте-Карло

Смотрите, например, это для объяснения этого метода.

Предостережения

  • Не совсем точно
  • Требуется много времени, чтобы сходиться к чему-либо полезному

преимущества

Весело :-)

perl -Mbignum -E '
    for(0 .. 1_000_000){
        srand;
        $x=rand; # Random x coordinate
        $y=rand; # Random Y coordinate
        $decision = $x**2 + $y**2 <=1 ? 1:0; # Is this point inside the unit circle?
        $circle += $decision;
        $not_circle += 1-$decision;
        $pi = 4*($circle/($circle+$not_circle)); 
        say $pi
     }'

Примечание: я сначала попробовал это без, srandно это застряло, 3.14и цифры после этого продолжали колебаться, никогда не сходясь. Вероятно, это потому, что через некоторое время PRNG начинает повторяться. Использование srandпозволит избежать этого или, по крайней мере, удлинить период псевдослучайной последовательности. Это все догадки, поэтому не стесняйтесь поправлять меня, если я ошибаюсь.

Джозеф Р.
источник
@ Amphiteót Не совсем уверен, что там происходит. Если это поможет, мой Perl v5.14.2. Я не очень хорошо разбираюсь в bignumоперациях в Perl, я боюсь, и я не знаю каких-либо конкретных частей вышеупомянутой программы, которые требуют более нового Perl. В любом случае, что интересно в этом, так это сам алгоритм. Попробуйте реализовать его на выбранном вами языке, если этот Perl не работает для вас.
Джозеф Р.
1
@ Амфите, я вижу. Редактирование решает вашу проблему?
Джозеф Р.
@ Amphiteót Вы можете попробовать добавить ($x,$y,$circle,$not_circle)=(0,0,0);перед циклом, чтобы убедиться, что все переменные определены перед использованием.
Джозеф Р.
@ Amphiteót Моя ошибка. Парень выше должен был быть (0,0,0,0).
Джозеф Р.
По этому вопросу /5.20.1: Имеет смысл, но не видел этого! Действительно ($x,$y,$circle,$not_circle)=(0,0,0,0). Через минуту или две он завис вокруг желаемого значения, затем он приблизился к 3.1409, прежде чем я остановился. Интересно и весело! Спасибо!
2

Вы можете использовать алгоритм spigot для пи. Следующая программа на Си от Dik Winter и Achim Flammenkamp произведет первые 15 000 цифр числа Пи, по одной цифре за раз.

a[52514],b,c=52514,d,e,f=1e4,g,h;main(){for(;b=c-=14;h=printf("%04d",e+d/f))for(e=d%=f;g=--b*2;d/=g)d=d*b+f*(h?a[b]:f/5),a[b]=d%--g;}
Даниэль Хеннебергер
источник
Контекст: вики , здесь и здесь .
1
Мне нравится алгоритм spigot для логарифмических констант Borwein, Bailey и Plouffe, однако, это не гольф-код, поэтому я могу улучшить читабельность вашего кода, переформатировав его? Также обратите внимание, что алгоритмы в стиле BPP могут выводить цифры для числа Пи только в базах степеней 2, по крайней мере, без использования дополнительной памяти.
Франки
@Franki ли форматирование кода изменить смысл или намерение сообщения? Если нет, все должно быть в порядке (и редактирование всегда можно откатить). Я не понимаю, как деобфускация некоторого кода может сделать что-то еще, кроме разъяснения.
11684
1
@syntaxerror Это должно произвести ровно 15 000 цифр перед остановкой. Выходные данные во втором цикле for производят 4 цифры числа pi и уменьшают загадочное число 52514 на 14. Тогда уравнение будет равно 4 * (52514/14), что равно 15004. Последние 14 значений в массиве игнорируются для принятия преимущество меньшего количества токенов, чтобы получить наше точное значение 15000.
Даниэль Хеннебергер
1
@ 11684 Нет, это действительно не изменит смысл или намерение кода. Тем не менее, я понял, что это не алгоритм spigot в стиле BBP для pi, а еще один, который кто-то еще уже деобфускировал здесь stackoverflow.com/a/25837097
Franki
2

PHP

Несколько примеров:

php -r "print pi();"
php -r 'echo M_PI;'
echo "<?=pi();" | php

Если вы хотите изменить точность, попробуйте:

php -d precision=100 -r 'echo pi();'

Размер числа с плавающей запятой зависит от платформы, хотя максимальное значение ~ 1.8e308 с точностью примерно 14 десятичных цифр является общим значением (формат 64-битного IEEE). [Подробнее]


Если вы ищете еще более точную точность, проверьте Rosetta Code или Code Golf SE для некоторых программных решений.

Связанный: Программное обеспечение, которое может вычислить ПИ как минимум до тысячи цифр в SR.SE

kenorb
источник
1

Вот скрипт, который печатает число с числом цифр, указанным пользователем (включая «.»).

pi.sh

#!/bin/bash
len=${1:-7}
echo "4*a(1)" | bc -l | cut -c 1-"$len"

выход

$ ./pi.sh 10
3.14159265

и со значением по умолчанию:

$ ./pi.sh
3.14159

Я видел людей, использующих scaleв качестве bcопции, но в моем случае ( bc 1.06.95) это не выводит правильное значение:

$ echo "scale=5;4*a(1)" | bc -l
3.14156

Обратите внимание на последнюю цифру.

fduff
источник
4
Вопрос говорит: «Я хочу указать, сколько цифр он печатает», что, строго говоря, неоднозначно - но я думаю, что ваш ответ не соответствует (по техническим причинам) при любой разумной интерпретации; Вы ./pi.sh 10печатаете девять цифр, считая начальные 3. Кроме того, вы указываете на ошибку округления, но ваши ./pi.sh 6выводы 3.1415, которые могут быть не оптимальными.
G-Man говорит: «Восстановите Монику»
Из памяти scale=Xопция bcНЕ будет округлять число, а просто обрезает число с десятой десятой цифрой.
syntaxerror
1

Мне нравится ответ Аби, но мне не понравилось, как БК менял последнюю цифру.

echo "scale=5; 4*a(1)" | bc -l
3.14156

Поэтому я удалил масштаб, используя printf, чтобы установить количество цифр.

printf "%0.5f\n" $(echo "4*a(1)" | bc -l)
3.14159
LinuxGuru
источник
Вы заметили, что после шкалы из 62 цифр все они равны 0, тогда как с оригинальной командой этого не происходит.
2
@ Amphiteót, потому что printfимеет строгое ограничение по числам с плавающей запятой по сравнению с bc. Они представлены doubleтипом языка C с точностью около 17 цифр, поэтому даже ненулевые цифры после примерно 17-й являются поддельными! ------ Я добавил ответ с правильным округлением результата, не ограничиваясьprintf . ------ Также, чтобы эта команда LC_ALL=C printf
работала
1

Что если ты не можешь на всю жизнь вспомнить эту arctanвещь? Или предположим, что вы даже не знаете, что эта функция существует bc, а затем попытайтесь запомнить это простое деление:

echo "scale=6; 355 / 113" | bc
3.141592

Будет работать только для 6 цифр, но для ненаучных расчетов это будет хорошо.

Если вы думаете, что не можете запомнить эти два числа, сначала напишите знаменатель, а затем числитель:

113 355

Или почему нет

11 33 55

«двойной 1, двойной 3, двойной 5». Все цифры странные. Для вычисления снова разделите 6-значное число пополам, поменяйте местами знаменатель и числитель, прежде чем делить их. Вот и все.

синтаксическая ошибка
источник
Что касается меня, мне 4 * arctan(1)гораздо легче запомнить эти 2 трехзначных числа ... Я бы легко использовал 335 вместо 355 или 133 вместо 113.
Джон У. Смит,
Ну, я думаю, что это вопрос личных предпочтений. :) Люди (как и я), которые могут легко запомнить (стационарные!) Номера телефонов, смогут запомнить два номера, как один телефонный номер. Это также поможет тем людям, которые в школе чувствовали, что тригонометрия была сделана злыми силами.
синтаксическая ошибка
1

Можно предположить, что OP заинтересован в короткой, легко запоминающейся команде оболочки для печати π - но вопрос на самом деле не говорит об этом. Этот ответ игнорирует это предположение и отвечает на вопрос строго в письменном виде;

Trivial?

Хотя уже есть 18 ответов, один подход все еще отсутствует - и с таким количеством ответов можно подумать, что он не единственный, которого не хватает:
тривиальный: как напечатать π? Просто напечатайте π!

Такой подход кажется слишком бесполезным, чтобы даже думать об этом, но я покажу, что у него есть свои достоинства:

оптимизированный

Обычно мы рассчитываем значение π. Я не понимаю, что мешает нам оптимизировать решение путем предварительного вычисления значения - это константа, любой компилятор сделает это.

Нам нужно некоторое количество цифр π с максимальной точностью. Таким образом, мы можем просто взять префикс константы в виде текста:

echo 3.1415926535897932384626433832795 | cut -b -7
3.14159

Вариант с явным аргументом для точности, например. для точности 5:

echo 3.1415926535897932384626433832795 | cut -b -$((2+5))
3.14159

преимущества

Максимальная точность может быть выбрана произвольно с помощью подходящей константы, рассчитанной с использованием одного из других ответов. Он ограничен только максимальной длиной командной строки.
Он имеет постоянную сложность времени для поиска значения.
Это делает все ограничения и ограничения очевидными, основываясь на низкой сложности реализации.
Он корректно обрабатывает точность, превышающую максимум, возвращая константу с полной доступной точностью (без трейлинга 0).
Так что это решение, хотя и тривиальное, имеет свои преимущества. Это может быть полезно, например, когда оно используется в функции оболочки.

минимальная

Функциональность вышеуказанного решения также может быть дополнена без создания процесса cut(предположим, echoчто это встроенная оболочка). Он использует команду printf(обычно встроенный) в несколько непонятным образом:
Константа полностью handeled как струна (используется формат %s), нет с плавающей точкой arithmethic участвует, так что пределы floatили doubleне применяются здесь.
Значение точности %sescape ( 5в приведенном ниже примере) указывает длину префикса строки для печати, что и является точностью. Это 3.часть printfформата, позволяющая избежать точного расчета.

$ printf "3.%.5s\n" 1415926535897932384626433832795 
3.14159

Альтернатива с точностью в качестве отдельного аргумента:

$ printf "3.%.*s\n" 5 1415926535897932384626433832795 
3.14159

Или немного более читабельным (обратите внимание на пробел между 3.и 14159..., они являются отдельными аргументами):

$ printf "%s%.5s\n" 3. 1415926535897932384626433832795
3.14159

Быстро

printfМожно ожидать, что использование варианта будет очень быстрым: поскольку printfоболочка встроена в обычные оболочки, такие как bashи zsh, она не создает никаких процессов.
Кроме того, он не касается какого-либо кода, связанного с плавающей точкой, а только манипулирует байтовыми массивами (явно не многобайтовыми символами). Это обычно быстрее, часто намного быстрее, чем использование плавающей запятой.

совместимость с printf

Часто есть причины для замены printf, /usr/bin/printfчтобы гарантировать последовательность или совместимость. В этом случае, я думаю, мы можем использовать встроенную функцию - что важно, поскольку использование /usr/bin/printfуменьшает «быстрое» преимущество, разворачивая процесс.
Распространенной проблемой printfсовместимости является формат вывода чисел в зависимости от локали. Разделение .для чисел может быть изменено на ,основе настроек локали; Но мы не используем числа, просто строковую константу, содержащую литерал .- не зависит от локали.
Стефан Шазелас отметил, что printf %.5sвzsh, считая символы, а не байты, как обычно. К счастью, наши константы используют только символы в нижнем ASCII-диапазоне, который кодируется одним байтом на символ в любой соответствующей кодировке, при условии, что мы используем общую UTF-8кодировку для Unicode, а не кодировку с фиксированной шириной.

Volker Siegel
источник
Обратите внимание, что printf %.5sэто символ (не байт), основанный на zsh (разумно, но против POSIX). ksh93«s %.5Lsявляется graphem основе.
Стефан Шазелас