Index: bp-xprofile/bp-xprofile-classes.php
===================================================================
--- bp-xprofile/bp-xprofile-classes.php
+++ bp-xprofile/bp-xprofile-classes.php
@@ -1094,7 +1094,7 @@
 		do_action_ref_array( 'xprofile_data_before_save', array( $this ) );
 
 		if ( $this->is_valid_field() ) {
-			if ( $this->exists() && !empty( $this->value ) && strlen( trim( $this->value ) ) ) {
+			if ( $this->exists() && strlen( trim( $this->value ) ) ) {
 				$result   = $wpdb->query( $wpdb->prepare( "UPDATE {$bp->profile->table_name_data} SET value = %s, last_updated = %s WHERE user_id = %d AND field_id = %d", $this->value, $this->last_updated, $this->user_id, $this->field_id ) );
 
 			} else if ( $this->exists() && empty( $this->value ) ) {
@@ -2431,6 +2431,8 @@
 		$this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' );
 		$this->name     = _x( 'Number', 'xprofile field type', 'buddypress' );
 
+		$this->accepts_null_value = true;
+
 		$this->set_format( '/^\d+$/', 'replace' );
 		do_action( 'bp_xprofile_field_type_number', $this );
 	}
@@ -2453,7 +2455,7 @@
 		$html = $this->get_edit_field_html_elements( array_merge(
 			array(
 				'type'  => 'number',
-				'value' => bp_get_the_profile_field_edit_value(),
+				'value' => (int) bp_get_the_profile_field_edit_value(),
 			),
 			$raw_properties
 		) );
Index: bp-xprofile/bp-xprofile-filters.php
===================================================================
--- bp-xprofile/bp-xprofile-filters.php
+++ bp-xprofile/bp-xprofile-filters.php
@@ -85,14 +85,15 @@
 function xprofile_sanitize_data_value_before_save ( $field_value, $field_id, $reserialize = true ) {
 
 	// Return if empty
-	if ( empty( $field_value ) )
-		return;
+	if ( empty( $field_value ) ) {
+		return $field_value;
+	}
 
 	// Value might be serialized
 	$field_value = maybe_unserialize( $field_value );
 
 	// Filter single value
-	if ( !is_array( $field_value ) ) {
+	if ( ! is_array( $field_value ) ) {
 		$kses_field_value     = xprofile_filter_kses( $field_value );
 		$filtered_field_value = wp_rel_nofollow( force_balance_tags( $kses_field_value ) );
 		$filtered_field_value = apply_filters( 'xprofile_filtered_data_value_before_save', $filtered_field_value, $field_value );
Index: bp-xprofile/bp-xprofile-functions.php
===================================================================
--- bp-xprofile/bp-xprofile-functions.php
+++ bp-xprofile/bp-xprofile-functions.php
@@ -256,13 +256,22 @@
 	if ( empty( $field_id ) )
 		return false;
 
-	if ( $is_required && ( empty( $value ) || !is_array( $value ) && !strlen( trim( $value ) ) ) )
+	if ( $is_required && ( empty( $value ) || !is_array( $value ) && !strlen( trim( $value ) ) ) ) {
 		return false;
+	}
 
 	$field          = new BP_XProfile_Field( $field_id );
-	$field_type_obj = bp_xprofile_create_field_type( BP_XProfile_Field::get_type( $field_id ) );
+	$field_type     = BP_XProfile_Field::get_type( $field_id );
+	$field_type_obj = bp_xprofile_create_field_type( $field_type );
+
+	// Certain types of fields (checkboxes, multiselects) may come through empty.
+	// Save as empty array so this isn't overwritten by the default on next edit.
+	if ( empty( $value ) && in_array( $field_type, array( 'multiselectbox', 'checkbox' ) ) ) {
+		$value = array();
+	}
 
-	// If the value is empty, then delete any field data that exists, unless the field is of a type where null values are semantically meaningful
+	// If the value is empty, then delete any field data that exists, unless the
+	// field is of a type where null values are semantically meaningful
 	if ( empty( $value ) && ! $field_type_obj->accepts_null_value ) {
 		xprofile_delete_field_data( $field_id, $user_id );
 		return true;
Index: bp-xprofile/bp-xprofile-screens.php
===================================================================
--- bp-xprofile/bp-xprofile-screens.php
+++ bp-xprofile/bp-xprofile-screens.php
@@ -105,12 +105,7 @@
 			$old_values = $new_values = array();
 			foreach ( (array) $posted_field_ids as $field_id ) {
 
-				// Certain types of fields (checkboxes, multiselects) may come through empty. Save them as an empty array so that they don't get overwritten by the default on the next edit.
-				if ( empty( $_POST['field_' . $field_id] ) ) {
-					$value = array();
-				} else {
-					$value = $_POST['field_' . $field_id];
-				}
+				$value = isset( $_POST['field_' . $field_id] ) ? $_POST['field_' . $field_id] : '';
 
 				if ( !xprofile_set_field_data( $field_id, bp_displayed_user_id(), $value, $is_required[$field_id] ) ) {
 					$errors = true;
Index: tests/testcases/xprofile/functions.php
===================================================================
--- tests/testcases/xprofile/functions.php
+++ tests/testcases/xprofile/functions.php
@@ -542,4 +542,20 @@
 
 		$this->assertSame( 'foo', $found );
 	}
+
+	/**
+	 * @group xprofile_set_field_data
+	 */
+	public function test_get_field_data_integer_zero() {
+		$u = $this->create_user();
+		$g = $this->factory->xprofile_group->create();
+		$f = $this->factory->xprofile_field->create( array(
+			'field_group_id' => $g,
+			'type' => 'number',
+			'name' => 'Pens',
+		) );
+		xprofile_set_field_data( $f, $u, 0 );
+
+		$this->assertEquals( 0, xprofile_get_field_data( 'Pens', $u ) );
+	}
 }
