user: Converte this assembly snippet into its equivalent C code:

```asm
<read_float>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %rdx,-0x48(%rbp)
  mov    %rcx,-0x50(%rbp)
  movl   $0x0,-0x24(%rbp)
  movl   $0x0,-0x20(%rbp)
  movl   $0x0,-0x1c(%rbp)
  mov    -0x38(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x38(%rbp),%rdx
  mov    -0x40(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x10(%rbp),%rax
  cmp    -0x8(%rbp),%rax
  jae    L38
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2d,%al
  jne    L38
  movl   $0x1,-0x1c(%rbp)
  addq   $0x1,-0x10(%rbp)
  jmp    L38
L91:
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <digit_to_num@plt>
  mov    %eax,-0x18(%rbp)
  cmpl   $0x0,-0x18(%rbp)
  js     L52
  mov    D0(%rip),%rax
  mov    (%rax),%eax
  movslq %eax,%rdx
  imul   $0x66666667,%rdx,%rdx
  shr    $0x20,%rdx
  sar    $0x2,%edx
  sar    $0x1f,%eax
  mov    %eax,%ecx
  mov    %edx,%eax
  sub    %ecx,%eax
  cmp    %eax,-0x24(%rbp)
  jl     L54
  mov    D33(%rip),%rax
  mov    (%rax),%eax
  neg    %eax
  jmp    L89
L54:
  mov    -0x24(%rbp),%edx
  mov    %edx,%eax
  shl    $0x2,%eax
  add    %edx,%eax
  add    %eax,%eax
  mov    %eax,-0x24(%rbp)
  mov    -0x18(%rbp),%eax
  add    %eax,-0x24(%rbp)
  addq   $0x1,-0x10(%rbp)
L38:
  mov    -0x10(%rbp),%rax
  cmp    -0x8(%rbp),%rax
  jb     L91
  jmp    L35
L52:
  nop
L35:
  mov    -0x10(%rbp),%rax
  cmp    -0x8(%rbp),%rax
  jae    L21
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2e,%al
  jne    L21
  addq   $0x1,-0x10(%rbp)
  jmp    L28
L50:
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <digit_to_num@plt>
  mov    %eax,-0x14(%rbp)
  cmpl   $0x0,-0x14(%rbp)
  js     L171
  mov    D0(%rip),%rax
  mov    (%rax),%eax
  movslq %eax,%rdx
  imul   $0x66666667,%rdx,%rdx
  shr    $0x20,%rdx
  sar    $0x2,%edx
  sar    $0x1f,%eax
  mov    %eax,%ecx
  mov    %edx,%eax
  sub    %ecx,%eax
  cmp    %eax,-0x24(%rbp)
  jl     L159
  mov    D33(%rip),%rax
  mov    (%rax),%eax
  neg    %eax
  jmp    L89
L159:
  mov    -0x24(%rbp),%edx
  mov    %edx,%eax
  shl    $0x2,%eax
  add    %edx,%eax
  add    %eax,%eax
  mov    %eax,-0x24(%rbp)
  mov    -0x14(%rbp),%eax
  add    %eax,-0x24(%rbp)
  addq   $0x1,-0x10(%rbp)
  subl   $0x1,-0x20(%rbp)
L28:
  mov    -0x10(%rbp),%rax
  cmp    -0x8(%rbp),%rax
  jb     L50
  jmp    L21
L171:
  nop
L21:
  mov    -0x48(%rbp),%rax
  mov    -0x20(%rbp),%edx
  mov    %edx,(%rax)
  cmpl   $0x0,-0x1c(%rbp)
  je     L57
  mov    -0x24(%rbp),%eax
  neg    %eax
  jmp    L129
L57:
  mov    -0x24(%rbp),%eax
L129:
  mov    -0x50(%rbp),%rdx
  mov    %eax,(%rdx)
  mov    -0x10(%rbp),%rax
  sub    -0x38(%rbp),%rax
L89:
  leave
  ret
```

assistant: ```c
int read_float(char *buf, size_t size, int *exponent_out, int *mantissa_out) {
  int mantissa = 0;
  int exponent = 0;
  bool neg = false;
  char *cursor = buf;
  char *end = buf + size;
  if (cursor < end && *cursor == '-') {
    neg = true;
    cursor++;
  }
  while (cursor < end) {
    int digit = digit_to_num(*cursor);
    if (digit < 0)
      break;
    if (mantissa >= (INT_MAX / 10))
      return -EOVERFLOW;
    mantissa *= 10;
    mantissa += digit;
    cursor++;
  }
  if (cursor < end && *cursor == '.') {
    cursor++;
    while (cursor < end) {
      int digit = digit_to_num(*cursor);
      if (digit < 0)
        break;
      if (mantissa >= (INT_MAX / 10))
        return -EOVERFLOW;
      mantissa *= 10;
      mantissa += digit;
      cursor++;
      exponent--;
    }
  }
  *exponent_out = exponent;
  *mantissa_out = neg ? -mantissa : mantissa;
  return cursor - buf;
}
```