PENF

February 27, 2026 · View on GitHub

Portability Environment for Fortran Poor People

A KISS pure Fortran 2003+ library for portable, parametrized numerical types — kind parameters, format strings, number ↔ string conversions, and more.

GitHub tag GitHub issues CI coverage

🔢 Kind Parameters
Integers I1PI8P and reals R4P/R8P/R16P, portable across compilers
🔄 Number ↔ String
str(), strz(), cton(), bstr(), bcton() — full round-trips
📐 Format Strings & Limits
Ready-made FI*P / FR*P formats and min/max values for every kind
📏 Bit & Byte Sizes
bit_size() / byte_size() extended to reals, integers, and characters
Pure Fortran 2003+
No C, no external deps — tested with gfortran ≥ 4.9.2 and ifort ≥ 12.x
🔓 Multi-licensed
GPL v3 · BSD 2/3-Clause · MIT
📦 Multiple build systems
fpm, FoBiS.py, CMake, Makefile
📖 Documented & Tested
API reference + doctests for all type variants

For full documentation (guide, API reference, examples, etc.) see the PENF website.


Authors

Contributions are welcome — see the Contributing page.

Copyrights

This project is distributed under a multi-licensing system:

Anyone interested in using, developing, or contributing to this project is welcome — pick the license that best fits your needs.


Quick start

use penf
call penf_init

real(R8P)    :: x = -1.0_R8P
integer(I4P) :: n = 42_I4P

print FR8P, x !  -0.100000000000000E+001
print FI4P, n !          42

Real kinds

ParameterPrecisionRangeSize
R16P33 digits[104931, 10+49311][10^{-4931},\ 10^{+4931}-1]128 bit
R8P15 digits[10307, 10+3071][10^{-307},\ 10^{+307}-1]64 bit
R4P6 digits[1037, 10+371][10^{-37},\ 10^{+37}-1]32 bit

Integer kinds

ParameterRangeSize
I8P[263, +2631][-2^{63},\ +2^{63}-1]64 bit
I4P[231, +2311][-2^{31},\ +2^{31}-1]32 bit
I2P[215, +2151][-2^{15},\ +2^{15}-1]16 bit
I1P[27, +271][-2^{7},\ +2^{7}-1]8 bit

Format Strings

Each kind has a matching format string for print / write statements:

KindFormat stringExample output
R16PFR16P = '(E42.33E4)'-0.100000000000000000000000000000000E+0001
R8PFR8P = '(E23.15E3)'-0.100000000000000E+001
R4PFR4P = '(E13.6E2)'-0.100000E+01
I8PFI8P = '(I20)' -1
I4PFI4P = '(I11)' -1
I2PFI2P = '(I6)' -1
I1PFI1P = '(I4)' -1

Install

FoBiS.py

Standalone — clone, build, and install in one command:

FoBiS.py install szaghi/PENF -mode static-gnu
FoBiS.py install szaghi/PENF -mode static-gnu --prefix /path/to/prefix

As a project dependency — declare PENF in your fobos and run fetch:

[dependencies]
deps_dir = src/third_party
PENF     = https://github.com/szaghi/PENF
FoBiS.py fetch           # fetch and build
FoBiS.py fetch --update  # re-fetch and rebuild

fpm

Add to your fpm.toml:

[dependencies]
PENF = { git = "https://github.com/szaghi/PENF" }

CMake

cmake -B build && cmake --build build

Makefile

make              # static library
make TESTS=yes    # build and run tests