diff --git a/src/terminal-screen.c b/src/terminal-screen.c
index 19773f9..883a6f6 100644
--- a/src/terminal-screen.c
+++ b/src/terminal-screen.c
@@ -182,6 +182,9 @@ static const TerminalRegexPattern url_regex_patterns[] = {
   { "(?:callto:|h323:|sip:)" USERCHARS_CLASS "[" USERCHARS ".]*(?:" PORT "/[a-z0-9]+)?\\@" HOST, FLAVOR_VOIP_CALL, G_REGEX_CASELESS  },
   { "(?:mailto:)?" USERCHARS_CLASS "[" USERCHARS ".]*\\@" HOSTCHARS_CLASS "+\\." HOST, FLAVOR_EMAIL, G_REGEX_CASELESS  },
   { "(?:news:|man:|info:)[-[:alnum:]\\Q^_{|}~!\"#$%&'()*+,./;:=?`\\E]+", FLAVOR_AS_IS, G_REGEX_CASELESS  },
+  /* The hex pattern should precede the decimal, so that we won't match a decimal number in the middle of a hexadecimal. */
+  { "0[Xx][\\dA-Fa-f]+", FLAVOR_NUMBER, 0 },
+  { "\\d+", FLAVOR_NUMBER, 0 },
 };
 
 static GRegex **url_regexes;
diff --git a/src/terminal-screen.h b/src/terminal-screen.h
index a168e57..c2a4bb5 100644
--- a/src/terminal-screen.h
+++ b/src/terminal-screen.h
@@ -30,7 +30,8 @@ typedef enum {
   FLAVOR_AS_IS,
   FLAVOR_DEFAULT_TO_HTTP,
   FLAVOR_VOIP_CALL,
-  FLAVOR_EMAIL
+  FLAVOR_EMAIL,
+  FLAVOR_NUMBER,
 } TerminalURLFlavour;
 
 /* Forward decls */
diff --git a/src/terminal-util.c b/src/terminal-util.c
index 2c4e0ff..d946c1f 100644
--- a/src/terminal-util.c
+++ b/src/terminal-util.c
@@ -26,6 +26,7 @@
 #include <time.h>
 #include <unistd.h>
 #include <sys/types.h>
+#include <langinfo.h>
 #include <errno.h>
 
 #include <glib.h>
@@ -44,6 +45,9 @@
 #include "terminal-window.h"
 #include "terminal-libgsystem.h"
 
+// TODO: does it need to be gettextized??
+static const char* iec_prefixes[] = { "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" };
+
 /**
  * terminal_util_show_error_dialog:
  * @transient_parent: parent of the future dialog window;
@@ -299,6 +303,7 @@ terminal_util_open_url (GtkWidget *parent,
       break;
     case FLAVOR_VOIP_CALL:
     case FLAVOR_AS_IS:
+    case FLAVOR_NUMBER:
       uri = g_strdup (orig_url);
       break;
     default:
@@ -951,3 +956,73 @@ terminal_util_bind_mnemonic_label_sensitivity (GtkWidget *widget)
                            (GtkCallback) terminal_util_bind_mnemonic_label_sensitivity,
                            NULL);
 }
+
+/**
+ * terminal_util_number_info:
+ * @str: a dec or hex number as string
+ *
+ * Returns: Useful info about @str, or %NULL if it's too large
+ */
+char *terminal_util_number_info (const char *str)
+{
+  gs_free char *decstr = NULL, *hextmp = NULL, *hexstr = NULL, *magnitudestr = NULL;
+  unsigned long long num;
+  gboolean exact = TRUE;
+  gboolean hex = FALSE;
+  int hextmplen, hexstrlen, i, j;
+  char *thousep;
+
+  errno = 0;
+  if (str[1] == 'x' || str[1] == 'X') {
+    num = strtoull(str + 2, NULL, 16);
+    hex = TRUE;
+  } else {
+    // TODO: do we want to handle octal? It's often misleading.
+    num = strtoull(str, NULL, 10);
+  }
+  if (errno) {
+    return NULL;
+  }
+
+  decstr = g_strdup_printf("%'llu", num);
+
+  /* Group hex chars by 4 */
+  // TODO: it's ugly as hell!
+  thousep = nl_langinfo(THOUSEP);
+  hextmp = g_strdup_printf("%llx", num);
+  hextmplen = strlen(hextmp);
+  hexstrlen = 2 + hextmplen + (hextmplen - 1) / 4 * strlen(thousep);
+  hexstr = g_malloc(hexstrlen + 1);
+  hexstr[0] = '0';
+  hexstr[1] = 'x';
+  hexstr[hexstrlen] = '\0';
+  i = 0; j = 2;
+  while (i < hextmplen) {
+    hexstr[j++] = hextmp[i++];
+    if (i < hextmplen && (hextmplen - i) % 4 == 0) {
+      strcpy(hexstr + j, thousep);
+      j += strlen(thousep);
+    }
+  }
+
+  if (num >= 1024) {
+    int pow = 0;
+    while (num >= 1024 * 1024) {
+      pow++;
+      if (num % 1024 != 0) exact = FALSE;
+      num /= 1024;
+    }
+    /* Show 2 fraction digits, always rounding downwards. Printf rounds floats to the nearest representable value,
+       so do the calculation with integers until we get 100-fold the desired value, and then switch to float. */
+    if (100 * num % 1024 != 0) exact = FALSE;
+    num = 100 * num / 1024;
+    // TODO: do we need to gettextize the "≈" sign?
+    magnitudestr = g_strdup_printf(" %s %.2f %s", exact ? "=" : "≈", (double) num / 100, iec_prefixes[pow]);
+  } else {
+    magnitudestr = g_strdup("");
+  }
+  return g_strdup_printf("%s = %s%s",
+                         hex ? hexstr : decstr,
+                         hex ? decstr : hexstr,
+                         magnitudestr);
+}
diff --git a/src/terminal-util.h b/src/terminal-util.h
index d4b5ae3..968ff9b 100644
--- a/src/terminal-util.h
+++ b/src/terminal-util.h
@@ -89,6 +89,8 @@ void terminal_g_settings_set_rgba_palette (GSettings      *settings,
 
 void terminal_util_bind_mnemonic_label_sensitivity (GtkWidget *widget);
 
+char *terminal_util_number_info (const char *str);
+
 G_END_DECLS
 
 #endif /* TERMINAL_UTIL_H */
diff --git a/src/terminal-window.c b/src/terminal-window.c
index 8a1881f..0eb9343 100644
--- a/src/terminal-window.c
+++ b/src/terminal-window.c
@@ -19,6 +19,7 @@
 
 #include "config.h"
 
+#include <errno.h>
 #include <string.h>
 #include <stdlib.h>
 
@@ -2038,7 +2039,7 @@ popup_clipboard_targets_received_cb (GtkClipboard *clipboard,
   TerminalScreen *screen = info->screen;
   GtkWidget *popup_menu;
   GtkAction *action;
-  gboolean can_paste, can_paste_uris, show_link, show_email_link, show_call_link;
+  gboolean can_paste, can_paste_uris, show_link, show_email_link, show_call_link, show_number;
 
   window = terminal_screen_popup_info_ref_window (info);
   if (window == NULL ||
@@ -2059,6 +2060,7 @@ popup_clipboard_targets_received_cb (GtkClipboard *clipboard,
   show_link = info->string != NULL && (info->flavour == FLAVOR_AS_IS || info->flavour == FLAVOR_DEFAULT_TO_HTTP);
   show_email_link = info->string != NULL && info->flavour == FLAVOR_EMAIL;
   show_call_link = info->string != NULL && info->flavour == FLAVOR_VOIP_CALL;
+  show_number = info->string != NULL && info->flavour == FLAVOR_NUMBER;
 
   action = gtk_action_group_get_action (priv->action_group, "PopupSendEmail");
   gtk_action_set_visible (action, show_email_link);
@@ -2072,6 +2074,17 @@ popup_clipboard_targets_received_cb (GtkClipboard *clipboard,
   gtk_action_set_visible (action, show_link);
   action = gtk_action_group_get_action (priv->action_group, "PopupCopyLinkAddress");
   gtk_action_set_visible (action, show_link);
+  action = gtk_action_group_get_action (priv->action_group, "PopupNumber");
+  if (show_number) {
+    gs_free char *numfmt = terminal_util_number_info(info->string);
+    if (numfmt == NULL) {
+      show_number = FALSE;
+    } else {
+      gtk_action_set_label (action, numfmt);
+    }
+  }
+  gtk_action_set_visible (action, show_number);
+  gtk_action_set_sensitive (action, FALSE);
 
   action = gtk_action_group_get_action (priv->action_group, "PopupCopy");
   gtk_action_set_sensitive (action, vte_terminal_get_has_selection (VTE_TERMINAL (screen)));
@@ -2605,6 +2618,9 @@ terminal_window_init (TerminalWindow *window)
       { "PopupCopyLinkAddress", NULL, N_("_Copy Link Address"), NULL,
         NULL,
         G_CALLBACK (popup_copy_url_callback) },
+      { "PopupNumber", NULL, "", NULL,
+        NULL,
+        NULL },
       { "PopupTerminalProfiles", NULL, N_("P_rofiles") },
       { "PopupCopy", "edit-copy", N_("Copy"), "",
         NULL,
diff --git a/src/terminal.xml b/src/terminal.xml
index d2065b3..3c30755 100644
--- a/src/terminal.xml
+++ b/src/terminal.xml
@@ -82,6 +82,7 @@
     <menuitem action="PopupCopyCallAddress" />
     <menuitem action="PopupOpenLink" />
     <menuitem action="PopupCopyLinkAddress" />
+    <menuitem action="PopupNumber" />
     <separator />
     <menuitem action="PopupNewTerminal" />
     <separator />
