What is the best way to verify controller arguments?
Here my working example:

.routing.yml

forcontu_pages.calculator:
  path: '/forcontu/pages/calculator/{num1}/{num2}'
  defaults:
    _controller: '\Drupal\forcontu_pages\Controller\ForcontuPagesController::calculator'
    num1: 20
    num2: 10
    _title: 'Calculator Page'
  requirements:
    _permission: 'access calculator'
    _custom_access:  '\Drupal\forcontu_pages\Controller\ForcontuPagesController::access'


ForcontuPagesController.php

use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Access\AccessResult;
...
  public function access(AccountInterface $account, $num1, $num2) {
    // Check permissions and combine that with any custom access checking needed. Pass forward
    // parameters from the route and/or request as needed.
    return AccessResult::allowedIf($num1 &gt; $num2);
  }
...


I just verify that $num1 is greater than $num2, but you can add your other params and your validations.

See that you can add more params:


  The access method arguments are resolved similar to normal
  routing. The following arguments are optionally available; they will
  be populated if they are properly type hinted:
  
  
  The slugs, like with normal routing.
  \Symfony\Component\HttpFoundation\Request $request
  \Symfony\Component\Routing\Route $route
  \Drupal\Core\Routing\RouteMatch $route_match
  \Drupal\Core\Session\AccountProxy $account
  


Read: What is a slug?

Reference:
Access checking on routes