#include <SPI.h>
#include <Button_SL.hpp>

// #define LEADING_ZEROS

//
// Global constants
//
constexpr byte CS_PIN {10};         // SPI CS PIN
constexpr uint8_t MAX_DIGITS {4};   // Max. displayable digits
constexpr uint8_t pinBtn {4};       // Button Pin

constexpr uint8_t segmentBits[10] = {
  //  edDcgbfa    // D = decimal point
    0b11010111,   // 0
    0b00010100,   // 1
    0b11001101,   // 2
    0b01011101,   // 3
    0b00011110,   // 4
    0b01011011,   // 5
    0b11011011,   // 6
    0b00010101,   // 7
    0b11011111,   // 8
    0b01011111,   // 9
};

//
// Global Variables/Objects
//
Btn::ButtonSL btn {pinBtn};

//
// Send data to the shift register
//
void writeShiftRegister(uint16_t pinData) {
  digitalWrite(CS_PIN, LOW);
  SPI.transfer(pinData >> 8);         // upper 8 bits = digit selection
  SPI.transfer((pinData & 0x00FF));   // lower 8 Bits = segments of the digit
  digitalWrite(CS_PIN, HIGH);
}

//
// Delete Digit on the display
//
void digitsOff() {
  writeShiftRegister(0x00);   // Clear Digits
}

//
// Show digit on the corresponding display position.
//
void digitToDisplay(uint8_t dgt[], uint8_t dotPos, uint8_t idx) {
  uint8_t mask = ~(1 << (idx));                                 // Set bit mask to display one of the four LED segments
  uint16_t bits {mask << 8};       // Highbyte (LED-Segment)
  bits |= segmentBits[dgt[idx]];   // Lowbyte (Digit)
  if (dotPos > 0 && dotPos < MAX_DIGITS && mask == (0xFF - (1 << dotPos))) { bits |= 0b00100000; }
  writeShiftRegister(bits);
}

//
// Divide the number into its decimal places
//
uint8_t breakNumberDown(uint8_t dgt[], uint16_t nbr) {
  dgt[3] = nbr / 1000;
  nbr %= 1000;
  dgt[2] = nbr / 100;
  nbr %= 100;
  dgt[1] = nbr / 10;
  nbr %= 10;
  dgt[0] = nbr;

  // Check whether leading zeros are present
  auto i {MAX_DIGITS - 1};
  for (; i > 0; --i) {
    if (dgt[i] > 0) { break; }
  }
  // Return the number - 1 of digits to be displayed without a leading zero;
  return i;
}

void sevenSegment(Btn::ButtonSL &b) {
  static uint8_t digits[MAX_DIGITS];
  static uint16_t dotPos;
  static uint8_t activeDigit {0};
  static uint8_t numDigits = 0;

  // Press the button to display a new number
  if (b.tick() == Btn::ButtonState::shortPressed) {
    uint16_t number = random(1, 10000);
    dotPos = random(0, MAX_DIGITS);
    numDigits = breakNumberDown(digits, number);
  }
  digitToDisplay(digits, dotPos, activeDigit);
#ifdef LEADING_ZEROS
  activeDigit = (activeDigit < MAX_DIGITS-1) ? activeDigit + 1 : 0;
#else
  // Decimal point position is greater than the number of digits -> 0.X[XX]
  numDigits = (dotPos > numDigits) ? dotPos : numDigits;
  activeDigit = (activeDigit < numDigits) ? activeDigit + 1 : 0;
#endif
}

//
// Main Program
//
void setup() {
  Serial.begin(115200);
  pinMode(CS_PIN, OUTPUT);
  SPI.begin();
  btn.begin();
  randomSeed(analogRead(A0));
}

void loop() { sevenSegment(btn); }
Press the button to display a new number
You should also connect 100nF capacitors between the respective VCC pins of the 74HC595 and GND
White: LED-Segment Green: Digit
74HC595
74HC595